From 3c070b58b29a4ff4ea8cdc913a1e236042ee4fda Mon Sep 17 00:00:00 2001 From: Kalle Viironen Date: Mon, 31 Mar 2014 16:09:22 +0300 Subject: Use configure -confirm-license option also in commercial Qt versions Pass the -confirm-license option to external license checker which is used in Qt commercial version. Change-Id: I62326d1e6a8307dae64535ecf2ced762130b7e8f Reviewed-by: Miikka Heikkinen Reviewed-by: Samuli Piippo --- configure | 3 ++- tools/configure/tools.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 52588c39d2..3fe8d43cf0 100755 --- a/configure +++ b/configure @@ -2773,7 +2773,8 @@ if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ]; EditionString="Technology Preview" elif [ $COMMERCIAL_USER = "yes" ]; then if test -x "$relpath/bin/licheck"; then - LicheckOutput=`$relpath/bin/licheck $relpath $outpath $PLATFORM $XPLATFORM` + LicheckOutput=`$relpath/bin/licheck $OPT_CONFIRM_LICENSE $relpath $outpath\ + $PLATFORM $XPLATFORM` if [ $? -ne 0 ]; then exit 1 else diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index e2a6f3cc8a..c0626e1950 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -71,8 +71,9 @@ void Tools::checkLicense(QMap &dictionary, const QString xQMakeSpec = QDir::toNativeSeparators(dictionary.value("XQMAKESPEC")); - QString command = QString("%1 %2 %3 %4 %5") + QString command = QString("%1 %2 %3 %4 %5 %6") .arg(licenseChecker, + dictionary.value("LICENSE_CONFIRMED", "no"), QDir::toNativeSeparators(sourcePath), QDir::toNativeSeparators(buildPath), qMakeSpec, xQMakeSpec); -- cgit v1.2.3 From b0718bfaf411738dda0ca1002e78ff570ec9a342 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Tue, 1 Apr 2014 03:19:11 +0300 Subject: Fix unused variable warning > qstring.cpp:5325:1: warning: 'defaultCollator' defined > but not used [-Wunused-variable] Change-Id: I29fe2006a678f4f0b3b504b90120c0e99d7090fb Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 01faad6f2d..7d409708bb 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5320,7 +5320,7 @@ int QString::localeAwareCompare(const QString &other) const return localeAwareCompare_helper(constData(), length(), other.constData(), other.length()); } -#if defined(QT_USE_ICU) +#if defined(QT_USE_ICU) && !defined(Q_OS_WIN32) && !defined(Q_OS_WINCE) && !defined (Q_OS_MAC) Q_GLOBAL_STATIC(QThreadStorage, defaultCollator) #endif -- cgit v1.2.3 From caf34b9f0ad66d8a1bcfaebcd33c676a0f7973cf Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Mon, 31 Mar 2014 17:23:39 +0300 Subject: WinRT winmain: Pass ImagePath as part of ImageParams in Xap packages ImageParams is used to pass arguments to main(), but when used the original argv[0] is dropped. To remedy this, expect argv[1] to contain the same value found in the Xap's ImagePath. Change-Id: I2fb3b9956304fdcdeec4424ea56289d56ad4fe0b Reviewed-by: Oliver Wolff --- src/winmain/qtmain_winrt.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 22d3f5bd91..eef23130f9 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -105,15 +105,29 @@ static void devMessageHandler(QtMsgType type, const QMessageLogContext &context, class AppContainer : public Microsoft::WRL::RuntimeClass { public: - AppContainer(int argc, char *argv[]) : m_argc(argc) + AppContainer(int argc, char *argv[]) : m_argc(argc), m_deleteArgv0(false) { m_argv.reserve(argc); - for (int i = 0; i < argc; ++i) + for (int i = 0; i < argc; ++i) { + // Workaround for empty argv[0] which occurs when WMAppManifest's ImageParams is used + // The second argument is taken to be the executable + if (i == 0 && argc >= 2 && !qstrlen(argv[0])) { + const QByteArray argv0 = QDir::current() + .absoluteFilePath(QString::fromLatin1(argv[1])).toUtf8(); + m_argv.append(qstrdup(argv0.constData())); + m_argc -= 1; + m_deleteArgv0 = true; + ++i; + continue; + } m_argv.append(argv[i]); + } } ~AppContainer() { + if (m_deleteArgv0) + delete[] m_argv[0]; for (int i = m_argc; i < m_argv.size(); ++i) delete[] m_argv[i]; } @@ -186,6 +200,7 @@ private: int m_argc; QVector m_argv; + bool m_deleteArgv0; EventRegistrationToken m_activationToken; }; -- cgit v1.2.3 From 30db2159aa54aff0c28054739e2204966c584d8c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 1 Apr 2014 10:27:42 +0200 Subject: Fix offset calculation on WinRT According to MSDN "the offset must be a multiple of the allocation granularity". We use this already for the win32 version by splitting into offsetLo and offsetHi. However, we did not convert it back to the correct argument passed for MapViewOfFileFromApp. Now all auto-tests for mapping succeed. Task-number: QTBUG-37773 Change-Id: I7e43f906cb93164b58f4e5e3f88388cdace865d7 Reviewed-by: Andrew Knight --- src/corelib/io/qfsfileengine_win.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index c974daab06..afc8deb1a0 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1034,6 +1034,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, LPVOID mapAddress = ::MapViewOfFile(mapHandle, access, offsetHi, offsetLo, size + extra); #else + offset = (offsetHi << 32) + offsetLo; LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, offset, size); #endif if (mapAddress) { -- cgit v1.2.3 From b4128d0f7dfe6fd5752c4ec3ecb03775ffda5949 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 26 Mar 2014 16:54:36 +0100 Subject: Use an offscreen surface in VAO cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid failing the makeCurrent() on iOS that does not currently support using a window with different contexts. Change-Id: I2e10ad7e382161625a78518d02ad94edaff591ca Reviewed-by: Sean Harmer Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglvertexarrayobject.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 22ca35a8c3..9dfd5b2a6f 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -359,9 +360,17 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() Q_D(QOpenGLVertexArrayObject); QOpenGLContext *oldContext = 0; + QScopedPointer offscreenSurface; if (d->context && ctx && d->context != ctx) { oldContext = ctx; - if (d->context->makeCurrent(oldContext->surface())) { + // Cannot just make the current surface current again with another context. + // The format may be incompatible and some platforms (iOS) may impose + // restrictions on using a window with different contexts. Create an + // offscreen surface (a pbuffer or a hidden window) instead to be safe. + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(d->context->format()); + offscreenSurface->create(); + if (d->context->makeCurrent(offscreenSurface.data())) { ctx = d->context; } else { qWarning("QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() failed to make VAO's context current"); -- cgit v1.2.3 From 0a86c3127241aed93be62c62c3927e9383c95fd1 Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Mon, 31 Mar 2014 15:25:44 +0300 Subject: When looking up the window hierarchy, stop at foreign windows If the window being activated is an embedded window, the parent window will be a foreign window (usually not even belonging to the current process); we shouldn't attempt to focus it. Task-number: QTBUG-37984 Change-Id: I2ea03a86b30bbc43cde643e18e0e1d020e5f2c84 Reviewed-by: Friedemann Kleint Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qapplication_qpa.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index 2f6e8acd87..5a4a4591bf 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -126,8 +126,15 @@ bool QApplicationPrivate::modalState() QWidget *qt_tlw_for_window(QWindow *wnd) { - while (wnd && !wnd->isTopLevel()) // QTBUG-32177, wnd might be a QQuickView embedded via window container. - wnd = wnd->parent(); + // QTBUG-32177, wnd might be a QQuickView embedded via window container. + while (wnd && !wnd->isTopLevel()) { + QWindow *parent = wnd->parent(); + // Don't end up in windows not belonging to this application + if (parent && parent->type() != Qt::ForeignWindow) + wnd = wnd->parent(); + else + break; + } if (wnd) foreach (QWidget *tlw, qApp->topLevelWidgets()) if (tlw->windowHandle() == wnd) -- cgit v1.2.3 From d8281a92b8eb1c5fa3e430c296f22a713cbe1808 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 1 Apr 2014 13:25:18 +0200 Subject: Do not set fwdcompat bit for a compatibility profile QGLFormat AMD drivers do weird things. Provide a workaround. Task-number: QTBUG-37909 Change-Id: Idabd6ebb6e1447cb9bd92c7711a50aaa8575b9d6 Reviewed-by: Sean Harmer --- src/opengl/qgl_qpa.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index fe4d1c363c..10e6ffde46 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -109,6 +109,11 @@ QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format) retFormat.setMajorVersion(format.majorVersion()); retFormat.setMinorVersion(format.minorVersion()); retFormat.setProfile(static_cast(format.profile())); + // QGLFormat has no way to set DeprecatedFunctions, that is, to tell that forward + // compatibility should not be requested. Some drivers fail to ignore the fwdcompat + // bit with compatibility profiles so make sure it is not set. + if (format.profile() == QGLFormat::CompatibilityProfile) + retFormat.setOption(QSurfaceFormat::DeprecatedFunctions); return retFormat; } -- cgit v1.2.3 From 9a14731b7cc95c18aad419ad7b8696a2f4ec39c9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 1 Apr 2014 10:36:12 +0200 Subject: Windows CE: Fix message about freetype font rendering. Task-number: QTBUG-37976 Change-Id: Ib4bf6ba8f62e2dc4f3860313442fa57c67f06d9a Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qplatformfunctions_wince.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qplatformfunctions_wince.h b/src/plugins/platforms/windows/qplatformfunctions_wince.h index 30fc66563e..65ce466086 100644 --- a/src/plugins/platforms/windows/qplatformfunctions_wince.h +++ b/src/plugins/platforms/windows/qplatformfunctions_wince.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -293,8 +293,8 @@ inline void OleUninitialize() inline DWORD GetGlyphOutline( HDC /*hdc*/, UINT /*uChar*/, INT /*fuFormat*/, GLYPHMETRICS * /*lpgm*/, DWORD /*cjBuffer*/, LPVOID /*pvBuffer*/, CONST MAT2 * /*lpmat2*/ ) { - qFatal("GetGlyphOutline not supported under Windows CE. Please try using freetype fontrendering, by" - "passing -platform windows:freetype as arguments to the application."); + qFatal("GetGlyphOutline() not supported under Windows CE. Please try using freetype font-rendering, by " + "passing the command line argument -platform windows:fontengine=freetype to the application."); return GDI_ERROR; } -- cgit v1.2.3 From 30b334ffebb13876d89395f6ac253b7741920efe Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 1 Apr 2014 18:18:02 +0200 Subject: Remove docs for javascript core jit configurability This should've been removed in commit 24f10256631cd1e0f461430a50be36b74f19e01e Task-number: QTBUG-37832 Change-Id: I3404f17c904dbb462773f40371d09b0e58a0930d Reviewed-by: Oswald Buddenhagen --- configure | 3 --- 1 file changed, 3 deletions(-) diff --git a/configure b/configure index 3fe8d43cf0..72679947be 100755 --- a/configure +++ b/configure @@ -2270,9 +2270,6 @@ Configure options: -system-sqlite ..... Use sqlite from the operating system. - -no-javascript-jit . Do not build the JavaScriptCore JIT compiler. - + -javascript-jit .... Build the JavaScriptCore JIT compiler. - -no-qml-debug ...... Do not build the in-process QML debugging support. + -qml-debug ......... Build the QML debugging support. -- cgit v1.2.3 From 2c36469a16f166a3b4e513cccf8186157952bba0 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Mon, 17 Mar 2014 17:45:08 +0100 Subject: QNX: Fix OpenGL autotest On QNX grabbing the frame buffer returns the content of the back buffer. In order to execute the OpenGL tests properly a swapBuffers is executed before in order to be able to retrieve the content of the front buffer. The patch also documents this platform behavior. Change-Id: I7a501818ec6eea061f2f54f95854f68cb72e0534 Reviewed-by: James McDonnell Reviewed-by: Sean Harmer --- src/opengl/qgl.cpp | 5 +++++ src/opengl/qglframebufferobject.cpp | 3 +++ tests/auto/opengl/qgl/tst_qgl.cpp | 30 +++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index e602a05af9..637cfc55a8 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4083,6 +4083,11 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext) Depending on your hardware, you can explicitly select which color buffer to grab with a glReadBuffer() call before calling this function. + + On QNX the back buffer is not preserved when swapBuffers() is called. The back buffer + where this function reads from, might thus not contain the same content as the front buffer. + In order to retrieve what is currently visible on the screen, swapBuffers() + has to be executed prior to this function call. */ QImage QGLWidget::grabFrameBuffer(bool withAlpha) { diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index d636da91b5..bd8bc2f64a 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -1114,6 +1114,9 @@ QGLFramebufferObjectFormat QGLFramebufferObject::format() const \fn QImage QGLFramebufferObject::toImage() const Returns the contents of this framebuffer object as a QImage. + + On QNX the back buffer is not preserved when a buffer swap occures. So this function + might return old content. */ QImage QGLFramebufferObject::toImage() const { diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp index 22f284e365..5831b33974 100644 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ b/tests/auto/opengl/qgl/tst_qgl.cpp @@ -1064,6 +1064,12 @@ void tst_QGL::glWidgetRendering() QVERIFY(w.beginOk); QVERIFY(w.engineType == QPaintEngine::OpenGL || w.engineType == QPaintEngine::OpenGL2); +#if defined(Q_OS_QNX) + // glReadPixels reads from the back buffer. On QNX the buffer is not preserved + // after a buffer swap. This is why we have to swap the buffer explicitly before calling + // grabFrameBuffer to retrieve the content of the front buffer. + w.swapBuffers(); +#endif QImage fb = w.grabFrameBuffer(false); qt_opengl_check_test_pattern(fb); } @@ -1104,6 +1110,9 @@ void tst_QGL::glFBOSimpleRendering() // buffer is actually missing. But that's probably ok anyway. void tst_QGL::glFBORendering() { +#if defined(Q_OS_QNX) + QSKIP("Reading the QGLFramebufferObject is unsupported on this platform"); +#endif if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QGLFramebufferObject not supported on this platform"); @@ -1280,7 +1289,7 @@ protected: fboPainter.end(); fboImage = fbo->toImage(); - widgetPainter.fillRect(-1, -1, width()+2, width()+2, Qt::blue); + widgetPainter.fillRect(-1, -1, width()+2, height()+2, Qt::blue); delete fbo; } @@ -1301,6 +1310,13 @@ void tst_QGL::glFBOUseInGLWidget() QVERIFY(w.widgetPainterBeginOk); QVERIFY(w.fboPainterBeginOk); +#if defined(Q_OS_QNX) + // glReadPixels reads from the back buffer. On QNX the buffer is not preserved + // after a buffer swap. This is why we have to swap the buffer explicitly before calling + // grabFrameBuffer to retrieve the content of the front buffer + w.swapBuffers(); +#endif + QImage widgetFB = w.grabFrameBuffer(false); QImage widgetReference(widgetFB.size(), widgetFB.format()); widgetReference.fill(0xff0000ff); @@ -1691,6 +1707,12 @@ void tst_QGL::replaceClipping() glw.paint(&referencePainter); referencePainter.end(); +#if defined(Q_OS_QNX) + // glReadPixels reads from the back buffer. On QNX the buffer is not preserved + // after a buffer swap. This is why we have to swap the buffer explicitly before calling + // grabFrameBuffer to retrieve the content of the front buffer + glw.swapBuffers(); +#endif const QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); // Sample pixels in a grid pattern which avoids false failures due to @@ -1802,6 +1824,12 @@ void tst_QGL::clipTest() glw.paint(&referencePainter); referencePainter.end(); +#if defined(Q_OS_QNX) + // glReadPixels reads from the back buffer. On QNX the buffer is not preserved + // after a buffer swap. This is why we have to swap the buffer explicitly before calling + // grabFrameBuffer to retrieve the content of the front buffer + glw.swapBuffers(); +#endif const QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); // Sample pixels in a grid pattern which avoids false failures due to -- cgit v1.2.3 From 3b18ea3cb85010c634bc177b93c823369b386cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 1 Apr 2014 14:14:39 +0200 Subject: Re-add missing test to kernel.pro Patch 9a08483d763dacfca6029f7a8970846e83df0e2a introduced a regression, tst_qmetatype test was not meant to be removed. Change-Id: I5456ffbbd9d9f8e461f828c6183e46dabf67952b Reviewed-by: Sergio Ahumada Reviewed-by: Thiago Macieira --- tests/auto/corelib/kernel/kernel.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro index 604a0f4fd8..4b3b2e824e 100644 --- a/tests/auto/corelib/kernel/kernel.pro +++ b/tests/auto/corelib/kernel/kernel.pro @@ -8,6 +8,7 @@ SUBDIRS=\ qmetaobjectbuilder \ qmetamethod \ qmetaproperty \ + qmetatype \ qmimedata \ qobject \ qpointer \ -- cgit v1.2.3 From ee3dea8d3fdc9477f3a54e5457e19be1d0c61de9 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 31 Mar 2014 14:48:29 +0200 Subject: [xcb] Fix build failure Build failure was introduced by 9bb634a6176c639bd6b52d58151e9927c30919d0. When linking with systems provided libxkbcommon, then DFLT_XKB_CONFIG_ROOT can't be accessed directly. The reason that this slip through CI is that on CI machines Qt is build with bundled version of libxkbcommon. In addition this patch improves keymap error message, by making it more explicit for users what could be the reasons for "keymap compilation" failures and what should be done to make input work. As it turns out this is a common issue on old systems, servers and some VNC clients. Task-number: QTBUG-37971 Change-Id: I77667a404150ee7ab8465a065e23ca5eea63c33b Reviewed-by: Uli Schlachter Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 28 +++++++++------------------- src/plugins/platforms/xcb/qxcbkeyboard.h | 2 +- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 92b24f4722..73cfb76bfc 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -663,23 +663,14 @@ void QXcbKeyboard::clearXKBConfig() memset(&xkb_names, 0, sizeof(xkb_names)); } -void QXcbKeyboard::printKeymapError(const QString &error) const +void QXcbKeyboard::printKeymapError(const char *error) const { - qWarning() << "Qt: " << error; - // check if XKB config root is a valid path - const QDir xkbRoot = qEnvironmentVariableIsSet("QT_XKB_CONFIG_ROOT") - ? QString::fromLocal8Bit(qgetenv("QT_XKB_CONFIG_ROOT")) - : DFLT_XKB_CONFIG_ROOT; - if (!xkbRoot.exists() || xkbRoot.dirName() != "xkb") { - qWarning() << "Set QT_XKB_CONFIG_ROOT to provide a valid XKB configuration data path, current search paths: " - << xkbRoot.path() << ". Use ':' as separator to provide several search paths."; - return; - } - qWarning() << "_XKB_RULES_NAMES property contains:" << "\nrules : " << xkb_names.rules << - "\nmodel : " << xkb_names.model << "\nlayout : " << xkb_names.layout << - "\nvariant : " << xkb_names.variant << "\noptions : " << xkb_names.options << - "\nIf this looks like a valid keyboard layout information then you might need to " - "update XKB configuration data on the system (http://cgit.freedesktop.org/xkeyboard-config/)."; + qWarning() << error << "Current XKB configuration data search paths are: "; + for (unsigned int i = 0; i < xkb_context_num_include_paths(xkb_context); ++i) + qWarning() << xkb_context_include_path_get(xkb_context, i); + qWarning() << "Use QT_XKB_CONFIG_ROOT environmental variable to provide an additional search path, " + "add ':' as separator to provide several search paths and/or make sure that XKB configuration data " + "directory contains recent enough contents, to update please see http://cgit.freedesktop.org/xkeyboard-config/ ."; } void QXcbKeyboard::updateKeymap() @@ -696,7 +687,7 @@ void QXcbKeyboard::updateKeymap() xkb_context = xkb_context_new((xkb_context_flags)0); } if (!xkb_context) { - printKeymapError("Failed to create XKB context!"); + printKeymapError("Qt: Failed to create XKB context!"); m_config = false; return; } @@ -731,8 +722,7 @@ void QXcbKeyboard::updateKeymap() if (xkb_keymap) { new_state = xkb_state_new(xkb_keymap); } else { - // failed to compile from RMLVO, give a verbose error message - printKeymapError("Qt: Failed to compile a keymap!"); + printKeymapError("Failed to compile a keymap!"); m_config = false; return; } diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 36ce1ea2f0..aefd9655ed 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -92,7 +92,7 @@ protected: QString keysymToUnicode(xcb_keysym_t sym) const; int keysymToQtKey(xcb_keysym_t keysym) const; int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const; - void printKeymapError(const QString &error) const; + void printKeymapError(const char *error) const; void readXKBConfig(); void clearXKBConfig(); -- cgit v1.2.3 From 7672f25f44357e854575cd04f9e9969ec2831dfa Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Fri, 28 Mar 2014 12:32:54 +0100 Subject: Enable the depth and stencil buffers by default in QOpenGLWidget QGLWidget rendered to the default framebuffer, which had a depth and stencil buffer attached by default. Keep this behavior by adding the attachments to the FBO by default in QOpenGLWidget. Change-Id: I6f72a444eac3d8eabb7a539ad12216f1e5d2183d Reviewed-by: Paul Olav Tvete Reviewed-by: Laszlo Agocs Reviewed-by: Gunnar Sletta --- src/widgets/kernel/qopenglwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 66aacadb28..8b0d7d525a 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -163,7 +163,7 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *) d->context.makeCurrent(d->surface()); delete d->fbo; // recreate when resized - d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio()); + d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio(), QOpenGLFramebufferObject::CombinedDepthStencil); d->fbo->bind(); QOpenGLFunctions *funcs = d->context.functions(); funcs->glBindTexture(GL_TEXTURE_2D, d->fbo->texture()); -- cgit v1.2.3 From f7971d37cbc7e2f25d0fac382f33f3c270c10598 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Fri, 28 Mar 2014 15:38:34 +0100 Subject: Add a way to share context between QtQuick and QtWidgets This will replace QSGContext::setSharedOpenGLContext. To be able to allow sharing the Chromium GL context with both QWebEngineView and QQuickWebEngineView, we need some way of setting the sharing within QtWidgets and QtQuick. Since they don't depend on one another this patch allows the sharing context to be set through QtGui. Change-Id: I91b365dd06ec925b4c5a99ac82c222778781fe8e Reviewed-by: Laszlo Agocs --- src/gui/kernel/qopenglcontext.cpp | 20 ++++++++++++++++++++ src/gui/kernel/qopenglcontext_p.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index e258218e85..55fe036fe0 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -230,6 +230,7 @@ public: }; static QThreadStorage qwindow_context_storage; +static QOpenGLContext *global_share_context = 0; #ifndef QT_NO_DEBUG QHash QOpenGLContextPrivate::makeCurrentTracker; @@ -330,6 +331,25 @@ QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context return previous; } +/*! + \internal + + This function is used by the Qt WebEngine to set up context sharing + across multiple windows. Do not use it for any other purpose. +*/ +void QOpenGLContextPrivate::setGlobalShareContext(QOpenGLContext *context) +{ + global_share_context = context; +} + +/*! + \internal +*/ +QOpenGLContext *QOpenGLContextPrivate::globalShareContext() +{ + return global_share_context; +} + int QOpenGLContextPrivate::maxTextureSize() { if (max_texture_size != -1) diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index 23c13b2e24..b21ff67068 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -244,6 +244,9 @@ public: static QOpenGLContext *setCurrentContext(QOpenGLContext *context); + static void setGlobalShareContext(QOpenGLContext *context); + static QOpenGLContext *globalShareContext(); + int maxTextureSize(); static QOpenGLContextPrivate *get(QOpenGLContext *context) -- cgit v1.2.3 From b94493e6c86d9744f9fe224bedd79daa188286c1 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Fri, 28 Mar 2014 18:10:52 +0100 Subject: Avoid an "OpenGL Error: 1282" output when resizing a QOpenGLWidget When we delete the previous FBO in QOpenGLWidget::resizeEvent while it is the currently bound FBO, the QOpenGLContextPrivate::current_fbo will not be updated and will try to be bound during the initialization of the new FBO. Fix the issue by explicitly releasing the FBO on destruction if it is current. Change-Id: Id049889c4857526750bbecf3dd27343e44449c12 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglframebufferobject.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 55edaf7baf..92a7330d6c 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -890,6 +890,8 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment QOpenGLFramebufferObject::~QOpenGLFramebufferObject() { Q_D(QOpenGLFramebufferObject); + if (isBound()) + release(); if (d->texture_guard) d->texture_guard->free(); -- cgit v1.2.3 From 5f6cbfb0701d0f4e87ac3656ffcbebdcd1577bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 28 Feb 2014 17:09:27 +0100 Subject: Android: Stop ART from complaining about missing thread names. The new Android jvm (ART) complains loudly if we attach without supplying a thread name. Task-number: QTBUG-35441 Change-Id: I962d613be0db50f3ca9a4c786b36003f31c9db14 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qjni.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 623662a628..437205bf92 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -44,6 +44,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -52,6 +53,11 @@ static inline QString keyBase() return QStringLiteral("%1%2%3"); } +static inline QByteArray threadBaseName() +{ + return QByteArrayLiteral("QtThread-"); +} + static QString qt_convertJString(jstring string) { QJNIEnvironmentPrivate env; @@ -179,7 +185,10 @@ QJNIEnvironmentPrivate::QJNIEnvironmentPrivate() { JavaVM *vm = QtAndroidPrivate::javaVM(); if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) { - if (vm->AttachCurrentThread(&jniEnv, 0) != JNI_OK) + const qulonglong id = reinterpret_cast(QThread::currentThreadId()); + const QByteArray threadName = threadBaseName() + QByteArray::number(id); + JavaVMAttachArgs args = { JNI_VERSION_1_6, threadName, Q_NULLPTR }; + if (vm->AttachCurrentThread(&jniEnv, &args) != JNI_OK) return; } -- cgit v1.2.3 From c9241a1a7baaef1fb5f61f28eea32ae75210e07d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 2 Apr 2014 13:50:27 +0200 Subject: Android: Don't accept the volume-key events. On Android the volume keys are by default connected to the global volume control and by accepting them we remove this feature. Meaning each application would need to re-implement this functionality. Ideally we should only accept the volume keys if they where accepted by the user to avoid overriding default behavior, but we currently don't have the infrastructure to do that. To revert back to the old behavior the env. variable QT_ANDROID_VOLUME_KEYS can be set. Task-number: QTBUG-36570 Change-Id: Ib053a40383f2de452f385b19f7795c2fc23fc4fe Reviewed-by: Paul Olav Tvete --- .../src/org/qtproject/qt5/android/QtActivityDelegate.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 e62b5dab82..b396dfdfa1 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -75,6 +75,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Method; +import java.lang.System; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -806,6 +807,13 @@ public class QtActivityDelegate c = composed; } + if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP + || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN + || keyCode == KeyEvent.KEYCODE_MUTE) + && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) { + return false; + } + m_lastChar = lc; if (keyCode == KeyEvent.KEYCODE_BACK) { m_backKeyPressedSent = !m_keyboardIsVisible; @@ -831,6 +839,13 @@ public class QtActivityDelegate } } + if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP + || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN + || keyCode == KeyEvent.KEYCODE_MUTE) + && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) { + return false; + } + if (keyCode == KeyEvent.KEYCODE_BACK && !m_backKeyPressedSent) { hideSoftwareKeyboard(); setKeyboardVisibility(false, System.nanoTime()); -- cgit v1.2.3 From 00cfcfefb353b7157b0d206fca68bd614c558ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lisandro=20Dami=C3=A1n=20Nicanor=20P=C3=A9rez=20Meyer?= Date: Fri, 14 Mar 2014 19:19:44 -0300 Subject: Enable s390[x] detection. It has been working in Debian for some time. Change-Id: Ib5741a4ba68bf95c7020336c84bc66257ff27809 Reviewed-by: Thiago Macieira --- src/corelib/global/qprocessordetection.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index cf7ee1b7aa..384df8fd54 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -269,12 +269,12 @@ S390 is big-endian. */ -// #elif defined(__s390__) -// # define Q_PROCESSOR_S390 -// # if defined(__s390x__) -// # define Q_PROCESSOR_S390_X -// # endif -// # define Q_BYTE_ORDER Q_BIG_ENDIAN +#elif defined(__s390__) +# define Q_PROCESSOR_S390 +# if defined(__s390x__) +# define Q_PROCESSOR_S390_X +# endif +# define Q_BYTE_ORDER Q_BIG_ENDIAN /* SuperH family, optional revision: SH-4A -- cgit v1.2.3 From d5ff16bc8ebf0f17fae3a28f08018db26567e81c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 2 Apr 2014 10:37:59 +0200 Subject: Fix access of tmpStorage in QODBCResult::exec(). Instead of using a list and appending / popping of elements, use a vector of constant size and access via index to avoid bookkeeping errors. Task-number: QTBUG-37831 Change-Id: Icb5a182626c63e693b04daaf7a2f70997d9aeae1 Reviewed-by: Mark Brand --- src/sql/drivers/odbc/qsql_odbc.cpp | 45 +++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index ac6d677d54..c950d2c2ef 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtSql module of the Qt Toolkit. @@ -1323,12 +1323,12 @@ bool QODBCResult::exec() if (isSelect()) SQLCloseCursor(d->hStmt); - QList tmpStorage; // holds temporary buffers - QVarLengthArray indicators(boundValues().count()); + QVector& values = boundValues(); + QVector tmpStorage(values.count(), QByteArray()); // holds temporary buffers + QVarLengthArray indicators(values.count()); memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN)); // bind parameters - only positional binding allowed - QVector& values = boundValues(); int i; SQLRETURN r; for (i = 0; i < values.count(); ++i) { @@ -1340,7 +1340,7 @@ bool QODBCResult::exec() *ind = SQL_NULL_DATA; switch (val.type()) { case QVariant::Date: { - QByteArray ba; + QByteArray &ba = tmpStorage[i]; ba.resize(sizeof(DATE_STRUCT)); DATE_STRUCT *dt = (DATE_STRUCT *)ba.constData(); QDate qdt = val.toDate(); @@ -1357,10 +1357,9 @@ bool QODBCResult::exec() (void *) dt, 0, *ind == SQL_NULL_DATA ? ind : NULL); - tmpStorage.append(ba); break; } case QVariant::Time: { - QByteArray ba; + QByteArray &ba = tmpStorage[i]; ba.resize(sizeof(TIME_STRUCT)); TIME_STRUCT *dt = (TIME_STRUCT *)ba.constData(); QTime qdt = val.toTime(); @@ -1377,10 +1376,9 @@ bool QODBCResult::exec() (void *) dt, 0, *ind == SQL_NULL_DATA ? ind : NULL); - tmpStorage.append(ba); break; } case QVariant::DateTime: { - QByteArray ba; + QByteArray &ba = tmpStorage[i]; ba.resize(sizeof(TIMESTAMP_STRUCT)); TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)ba.constData(); QDateTime qdt = val.toDateTime(); @@ -1412,7 +1410,6 @@ bool QODBCResult::exec() (void *) dt, 0, *ind == SQL_NULL_DATA ? ind : NULL); - tmpStorage.append(ba); break; } case QVariant::Int: r = SQLBindParameter(d->hStmt, @@ -1503,6 +1500,7 @@ bool QODBCResult::exec() break; case QVariant::String: if (d->unicode) { + QByteArray &ba = tmpStorage[i]; QString str = val.toString(); if (*ind != SQL_NULL_DATA) *ind = str.length() * sizeof(SQLTCHAR); @@ -1510,7 +1508,7 @@ bool QODBCResult::exec() if (bindValueType(i) & QSql::Out) { const QVarLengthArray a(toSQLTCHAR(str)); - QByteArray ba((const char *)a.constData(), a.size() * sizeof(SQLTCHAR)); + ba = QByteArray((const char *)a.constData(), a.size() * sizeof(SQLTCHAR)); r = SQLBindParameter(d->hStmt, i + 1, qParamType[bindValueType(i) & QSql::InOut], @@ -1521,10 +1519,9 @@ bool QODBCResult::exec() (void *)ba.data(), ba.size(), ind); - tmpStorage.append(ba); break; } - QByteArray strba((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR)); + ba = QByteArray ((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR)); r = SQLBindParameter(d->hStmt, i + 1, qParamType[bindValueType(i) & QSql::InOut], @@ -1532,15 +1529,15 @@ bool QODBCResult::exec() strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, strSize, 0, - (SQLPOINTER)strba.constData(), - strba.size(), + (SQLPOINTER)ba.constData(), + ba.size(), ind); - tmpStorage.append(strba); break; } else { - QByteArray str = val.toString().toUtf8(); + QByteArray &str = tmpStorage[i]; + str = val.toString().toUtf8(); if (*ind != SQL_NULL_DATA) *ind = str.length(); int strSize = str.length(); @@ -1555,12 +1552,11 @@ bool QODBCResult::exec() (void *)str.constData(), strSize, ind); - tmpStorage.append(str); break; } // fall through default: { - QByteArray ba = val.toByteArray(); + QByteArray &ba = tmpStorage[i]; if (*ind != SQL_NULL_DATA) *ind = ba.size(); r = SQLBindParameter(d->hStmt, @@ -1573,7 +1569,6 @@ bool QODBCResult::exec() (void *) ba.constData(), ba.length() + 1, ind); - tmpStorage.append(ba); break; } } if (r != SQL_SUCCESS) { @@ -1617,16 +1612,16 @@ bool QODBCResult::exec() for (i = 0; i < values.count(); ++i) { switch (values.at(i).type()) { case QVariant::Date: { - DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.takeFirst().constData()); + DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.at(i).constData()); values[i] = QVariant(QDate(ds.year, ds.month, ds.day)); break; } case QVariant::Time: { - TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.takeFirst().constData()); + TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.at(i).constData()); values[i] = QVariant(QTime(dt.hour, dt.minute, dt.second)); break; } case QVariant::DateTime: { TIMESTAMP_STRUCT dt = *((TIMESTAMP_STRUCT*) - tmpStorage.takeFirst().constData()); + tmpStorage.at(i).constData()); values[i] = QVariant(QDateTime(QDate(dt.year, dt.month, dt.day), QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000))); break; } @@ -1642,7 +1637,7 @@ bool QODBCResult::exec() case QVariant::String: if (d->unicode) { if (bindValueType(i) & QSql::Out) { - QByteArray first = tmpStorage.takeFirst(); + const QByteArray &first = tmpStorage.at(i); QVarLengthArray array; array.append((SQLTCHAR *)first.constData(), first.size()); values[i] = fromSQLTCHAR(array, first.size()/sizeof(SQLTCHAR)); @@ -1652,7 +1647,7 @@ bool QODBCResult::exec() // fall through default: { if (bindValueType(i) & QSql::Out) - values[i] = tmpStorage.takeFirst(); + values[i] = tmpStorage.at(i); break; } } if (indicators[i] == SQL_NULL_DATA) -- cgit v1.2.3 From 0dbd8c0be75c21acf96016ec1c43e26bc0cab036 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 2 Apr 2014 10:26:20 +0200 Subject: Be less verbose about invalid keysyms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Report invalid keysyms only when DEBUG_GENERATOR is defined. It is not unusal that Qt applications are used on old linux distributions where Compose files might be far behind the current development, therefore we should be less verbose when encountering invalid keysyms. On Red Hat 5 compose key plugin reports ~3200 lines of warning messages: "Qt Warning - invalid keysym: U1001D1BC" "Qt Warning - invalid keysym: U1001D16F" "Qt Warning - invalid keysym: U1001D1BA" "Qt Warning - invalid keysym: U1001D165" "Qt Warning - invalid keysym: U1001D16F" ... Task-number: QTBUG-34483 Change-Id: If0c51d300508ef164ad7fc59b0a76a838cd5a3b9 Reviewed-by: Frederik Gladhorn Reviewed-by: Jørgen Lind --- src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 8bbb490022..ea0b5261c4 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -430,8 +430,10 @@ void TableGenerator::parseKeySequence(char *line) elem.keys[i] = XKB_KEY_dead_invertedbreve; else if (!strcmp(sym, "dead_double_grave")) elem.keys[i] = XKB_KEY_dead_doublegrave; +#ifdef DEBUG_GENERATOR else qWarning() << QString("Qt Warning - invalid keysym: %1").arg(sym); +#endif } } else { elem.keys[i] = 0; -- cgit v1.2.3 From 4dd9a020017b0663b5b51883809721351c3e1f89 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 1 Apr 2014 12:17:14 +0300 Subject: d3dcompiler_qt: Fix default precompiled path The trailing slash was missing, which caused the resulting path to be wrong. Change-Id: Iaa9dee15e744307c2d438181964b71c412fd9709 Reviewed-by: Oliver Wolff --- src/angle/src/d3dcompiler/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/angle/src/d3dcompiler/main.cpp b/src/angle/src/d3dcompiler/main.cpp index 63ee1cf976..7647319396 100644 --- a/src/angle/src/d3dcompiler/main.cpp +++ b/src/angle/src/d3dcompiler/main.cpp @@ -207,7 +207,7 @@ HRESULT WINAPI D3DCompile( if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_BINARY_DIR")) precompiledPath = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_BINARY_DIR")); else - precompiledPath = QStringLiteral(":/qt.d3dcompiler"); // Default QRC path + precompiledPath = QStringLiteral(":/qt.d3dcompiler/"); // Default QRC path if (QDir(precompiledPath).exists()) binaryPaths.append(precompiledPath); -- cgit v1.2.3 From 828cfb4019939a39c84e5c5e17dc8cb52e9f63fd Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 2 Apr 2014 17:38:17 +0200 Subject: Avoid double clicks confusing popups Setting qt_button_down on DblClick is dubious and breaks popups like menus since they won't appear correctly on every click anymore when clicking on them rapidly several times. Task-number: QTBUG-37891 Change-Id: Ic6cbbbe8b42891d2f9fa2ff66aa42bb89230d896 Reviewed-by: Gabriel de Dietrich Reviewed-by: Rick Stockton Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidgetwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index ef138267bb..41a3dcc048 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -486,7 +486,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (!widget) widget = m_widget; - if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) + if (event->type() == QEvent::MouseButtonPress) qt_button_down = widget; QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(), -- cgit v1.2.3 From b11adb825c4dfc8429695947cef8f9e3253ad0c2 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 17 Mar 2014 10:16:08 +0100 Subject: Logging: Be also more strict with value of logging rule Only accept lower-case "true" and "false", as documented. The old check didn't match either the documentation, nor the QSettings/ QVariant behavior (where, for a boolean value, any lower-cased content that not empty, "0" or "false" is considered true). Change-Id: I317d29c16a27f862001b9dff02e8298df8acf5a6 Reviewed-by: Friedemann Kleint Reviewed-by: Alex Blasche --- src/corelib/io/qloggingregistry.cpp | 13 ++++++++----- .../corelib/io/qloggingregistry/tst_qloggingregistry.cpp | 9 ++++++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index 7e6883fd14..575150f148 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -218,11 +218,14 @@ void QLoggingSettingsParser::setContent(QTextStream &stream) if ((equalPos != -1) && (line.lastIndexOf(QLatin1Char('=')) == equalPos)) { const QStringRef pattern = line.leftRef(equalPos); - const QStringRef value = line.midRef(equalPos + 1); - bool enabled = (value.compare(QLatin1String("true"), - Qt::CaseInsensitive) == 0); - QLoggingRule rule(pattern, enabled); - if (rule.flags != 0) + const QStringRef valueStr = line.midRef(equalPos + 1); + int value = -1; + if (valueStr == QLatin1String("true")) + value = 1; + else if (valueStr == QLatin1String("false")) + value = 0; + QLoggingRule rule(pattern, (value == 1)); + if (rule.flags != 0 && (value != -1)) _rules.append(rule); else warnMsg("Ignoring malformed logging rule: '%s'", line.toUtf8().constData()); diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp index 3064fd1320..5623990bd1 100644 --- a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp +++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp @@ -306,10 +306,13 @@ private slots: void QLoggingRegistry_checkErrors() { QLoggingSettingsParser parser; - QString warnMsg = QString("Ignoring malformed logging rule: '***=false'"); - QTest::ignoreMessage(QtWarningMsg, warnMsg.toLocal8Bit().constData()); + QTest::ignoreMessage(QtWarningMsg, "Ignoring malformed logging rule: '***=false'"); + QTest::ignoreMessage(QtWarningMsg, "Ignoring malformed logging rule: '*=0'"); + QTest::ignoreMessage(QtWarningMsg, "Ignoring malformed logging rule: '*=TRUE'"); parser.setContent("[Rules]\n" - "***=false\n"); + "***=false\n" + "*=0\n" + "*=TRUE\n"); QVERIFY(parser.rules().isEmpty()); } }; -- cgit v1.2.3 From d6202762c135fbf5f1242911cf2455ff687f328e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 24 Mar 2014 10:10:50 +0100 Subject: OS X: Fix QRubberBand drawing on retina displays Extend the existing rect adjustment to cover the upper/left edges as well. Check for a valid rect before drawing. Task-number: QTBUG-34534 Change-Id: I156abf4fb52924c350ec24fb44eadca86b2d5339 Reviewed-by: Gabriel de Dietrich Reviewed-by: Steve Mokris --- src/widgets/styles/qmacstyle_mac.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 55e808e9ba..08221ce83a 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -4414,7 +4414,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QPen pen(strokeColor); p->setPen(pen); p->setBrush(fillColor); - p->drawRect(opt->rect.adjusted(0, 0, -1, -1)); + QRect adjusted = opt->rect.adjusted(1, 1, -1, -1); + if (adjusted.isValid()) + p->drawRect(adjusted); p->setPen(oldPen); p->setBrush(oldBrush); } -- cgit v1.2.3 From 66178447e91f56eaeaee203171b9355399d3bb5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 21 Mar 2014 13:48:18 +0100 Subject: Mac: Use QString::toNSString in QtBase. The string is now autoreleased. This fixes a memory leak in qt_mac_QStringListToNSMutableArrayVoid Task-number: QTBUG-20347 Change-Id: I11ebeb264af4c8ce98968f2221eea772f24c12d4 Reviewed-by: Gabriel de Dietrich Reviewed-by: Konstantin Ritt --- src/corelib/io/qfilesystemwatcher_fsevents.mm | 2 +- src/plugins/platforms/cocoa/qcocoahelpers.mm | 2 +- src/plugins/platforms/cocoa/qcocoamenuloader.mm | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm index bfcae2a3a2..981d663694 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents.mm +++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm @@ -478,7 +478,7 @@ bool QFseventsFileSystemWatcherEngine::startStream() NSMutableArray *pathsToWatch = [NSMutableArray arrayWithCapacity:watchedPaths.size()]; for (PathRefCounts::const_iterator i = watchedPaths.begin(), ei = watchedPaths.end(); i != ei; ++i) - [pathsToWatch addObject:reinterpret_cast(QCFString::toCFStringRef(i.key()))]; + [pathsToWatch addObject:i.key().toNSString()]; struct FSEventStreamContext callBackInfo = { 0, diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index a73944c07c..9850f83dea 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -74,7 +74,7 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list) { NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()]; for (int i=0; i(QCFString::toCFStringRef(list[i]))]; + [result addObject:list[i].toNSString()]; } return result; } diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 29fc0fb674..60bc3b5a55 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -115,14 +115,13 @@ QT_END_NAMESPACE showAllItem = [[appMenu itemWithTitle:@"Show All"] retain]; // Get the names in the nib to match the app name set by Qt. - const NSString *appName = reinterpret_cast(QCFString::toCFStringRef(qt_mac_applicationName())); + const NSString *appName = qt_mac_applicationName().toNSString(); [quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication" withString:const_cast(appName)]]; [hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication" withString:const_cast(appName)]]; [aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication" withString:const_cast(appName)]]; - [appName release]; // Disable the items that don't do anything. If someone associates a QAction with them // They should get synced back in. [preferencesItem setEnabled:NO]; -- cgit v1.2.3 From acebf6771236a31889c1e888f3ffc5aee1ab9124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 25 Mar 2014 14:56:09 +0100 Subject: Cocoa: Close ToolTips on parent window move. Treat Qt::ToolTip windows the same way as Qt::Popup windows: The parent window keeps track visible transient child windows of this type and closes them when appropriate. This improves the locator popup window behavior in Qt Creator: It now closes when moving the main Qt Creator window. Change-Id: Ibc5d0713469b7c9aba2fd13fb1eb559706c8c4ed Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoawindow.mm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index b27e1b03db..df15b008ab 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -619,11 +619,13 @@ void QCocoaWindow::setVisible(bool visible) // update the window geometry if there is a parent. setGeometry(window()->geometry()); - // Register popup windows so that the parent window can - // close them when needed. - if (window()->type() == Qt::Popup) { + // Register popup windows so that the parent window can close them when needed. + if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) { // qDebug() << "transientParent and popup" << window()->type() << Qt::Popup << (window()->type() & Qt::Popup); parentCocoaWindow->m_activePopupWindow = window(); + } + + if (window()->type() == Qt::Popup) { // QTBUG-30266: a window should not be resizable while a transient popup is open // Since this isn't a native popup, the window manager doesn't close the popup when you click outside NSUInteger parentStyleMask = [parentCocoaWindow->m_nsWindow styleMask]; -- cgit v1.2.3 From bdf55f62a258cbd5e3844775a992415e22373387 Mon Sep 17 00:00:00 2001 From: Kari Pihkala Date: Tue, 18 Mar 2014 10:16:19 +0200 Subject: Change the hidpi cursor hotspot coordinate mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All hidpi coordinates in Qt are device independent points and the hidpi cursor hotspot should follow that convention. Change-Id: Id5295cae7a463e9a3ea85d2b0a18a5020dc97656 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoacursor.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 592bfc8e50..b81b9a0b1c 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -308,8 +308,7 @@ NSCursor *QCocoaCursor::createCursorFromBitmap(const QBitmap *bitmap, const QBit NSCursor *QCocoaCursor::createCursorFromPixmap(const QPixmap pixmap, const QPoint hotspot) { - NSPoint hotSpot = NSMakePoint(hotspot.x() / pixmap.devicePixelRatio(), - hotspot.y() / pixmap.devicePixelRatio()); + NSPoint hotSpot = NSMakePoint(hotspot.x(), hotspot.y()); NSImage *nsimage; if (pixmap.devicePixelRatio() > 1.0) { QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio(); -- cgit v1.2.3 From 2d8b40439da7f3edbed3cfa7354f714686d6cdea Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Tue, 18 Mar 2014 09:03:36 -0700 Subject: Cocoa: Fix crash when disconnecting an AirDisplay monitor. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are some cases where unplugging a monitor temporarily leaves a QCocoaScreen object with an invalid m_screenIndex. Debugging shows that the OS does not report the screen update before Qt attempts a repaint. This calls devicePixelRatio(), which calls osScreen(), and the index for the screen is out of bounds. By temporarily exiting updateGeometry() when the screen is unavailable, we avoid the crash. The OS quickly reports the monitor state change and everything returns to normal, unnoticed to application. Task-number: QTBUG-37606 Change-Id: Iacb2ff22bd3df72a5d87b2289242fb393625af57 Reviewed-by: Gabriel de Dietrich Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 412818ae47..9d5388d33b 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -81,12 +81,16 @@ QCocoaScreen::~QCocoaScreen() NSScreen *QCocoaScreen::osScreen() const { - return [[NSScreen screens] objectAtIndex:m_screenIndex]; + NSArray *screens = [NSScreen screens]; + return ((NSUInteger)m_screenIndex < [screens count]) ? [screens objectAtIndex:m_screenIndex] : nil; } void QCocoaScreen::updateGeometry() { NSScreen *nsScreen = osScreen(); + if (!nsScreen) + return; + NSRect frameRect = [nsScreen frame]; if (m_screenIndex == 0) { @@ -143,7 +147,8 @@ qreal QCocoaScreen::devicePixelRatio() const { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { - return qreal([osScreen() backingScaleFactor]); + NSScreen * screen = osScreen(); + return qreal(screen ? [screen backingScaleFactor] : 1.0); } else #endif { -- cgit v1.2.3 From afacf694d5a6f34b88989e76971d70d700ce4949 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Tue, 28 Jan 2014 12:53:10 +0100 Subject: Use Finder bundle identifier over path for OS X bundle detection Currently, checking if Finder is the application returned for opening a bundle is done using its absolute path. Finder might be relocated in future OS X versions which makes this approach less clean. Using Finder's bundle identifier allows us to ignore where it is stored in the filesystem as the identifier will not change. Task-number: QTBUG-31884 Change-Id: Ib4c3412fb206fadda04eb547bc6a4eef02ee949a Reviewed-by: Oswald Buddenhagen Reviewed-by: Jake Petroules Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemengine_unix.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 6c0f31fb55..eabedaa80a 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -113,9 +113,10 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e &application); if (application) { - CFStringRef path = CFURLGetString(application); - QString applicationPath = QCFString::toQString(path); - if (applicationPath != QLatin1String("file://localhost/System/Library/CoreServices/Finder.app/")) + QCFType bundle = CFBundleCreate(kCFAllocatorDefault, application); + CFStringRef identifier = CFBundleGetIdentifier(bundle); + QString applicationId = QCFString::toQString(identifier); + if (applicationId != QLatin1String("com.apple.finder")) return true; } } -- cgit v1.2.3 From 4bbf313e9d3cab70c6dab6da4c03bf2ad60aa760 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Fri, 28 Mar 2014 15:40:28 +0100 Subject: Fix UI squishing when using QWidget::setRenderToTexture When resizing a window, a window might not be resized synchronously with its backing store. We need to use the actual texture size as the transform to avoid stretching the rendered texture. Change-Id: I945f6d190577ccdcb54483a267a1e42df1ca3156 Reviewed-by: Paul Olav Tvete Reviewed-by: Laszlo Agocs --- src/gui/painting/qplatformbackingstore.cpp | 10 ++++++---- src/gui/painting/qplatformbackingstore.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 710d84e3aa..6425aa065e 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -247,14 +247,14 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft); } - GLuint textureId = toTexture(deviceRegion(region, window)); + GLuint textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize); if (!textureId) return; funcs->glEnable(GL_BLEND); funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect); d_ptr->blitter->setSwizzleRB(true); d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); d_ptr->blitter->setSwizzleRB(false); @@ -282,6 +282,7 @@ QImage QPlatformBackingStore::toImage() const backingstore as an OpenGL texture. \a dirtyRegion is the part of the backingstore which may have changed since the last call to this function. The caller of this function must ensure that there is a current context. + The size of the texture is returned in \a textureSize. The ownership of the texture is not transferred. The caller must not store the return value between calls, but instead call this function before each use. @@ -291,7 +292,7 @@ QImage QPlatformBackingStore::toImage() const content using toImage() and performs a texture upload. */ -GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const +GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize) const { QImage image = toImage(); QSize imageSize = image.size(); @@ -325,7 +326,8 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, const_cast(image.constBits())); - d_ptr->textureSize = imageSize; + if (textureSize) + *textureSize = imageSize; } else { funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); QRect imageRect = image.rect(); diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index 76fd3d40b4..4728622cac 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -111,7 +111,7 @@ public: #ifndef QT_NO_OPENGL virtual void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, QPlatformTextureList *textures, QOpenGLContext *context); virtual QImage toImage() const; - virtual GLuint toTexture(const QRegion &dirtyRegion) const; + virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize) const; #endif virtual void resize(const QSize &size, const QRegion &staticContents) = 0; -- cgit v1.2.3 From dfb70fbfc47bf766e13986add490372d45db8050 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Mon, 31 Mar 2014 10:47:49 +0200 Subject: Doc: Fix Qt Gui filter name in Assistant Use bookcase for the filter name like the rest of the modules. Change-Id: I9690d0b6a6f3abb11837120da75832475b975b5d Reviewed-by: Jerome Pasion --- src/gui/doc/qtgui.qdocconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index e3ec216f9b..b1707e1eef 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -16,7 +16,7 @@ qhp.QtGui.indexTitle = Qt GUI qhp.QtGui.indexRoot = qhp.QtGui.filterAttributes = qtgui $QT_VERSION qtrefdoc -qhp.QtGui.customFilters.Qt.name = Qtgui $QT_VERSION +qhp.QtGui.customFilters.Qt.name = QtGui $QT_VERSION qhp.QtGui.customFilters.Qt.filterAttributes = qtgui $QT_VERSION qhp.QtGui.subprojects = classes -- cgit v1.2.3 From 24656de7e6647652c3ac4b0aaabdc52b02c67668 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 2 Apr 2014 15:11:10 +0200 Subject: Fix QPushButton autotest In the sizeHint test the show command was replaced by showNormal. This fixes the test an all platforms where show translates to showFullScreen. Change-Id: I307790a6987c61a57679094b26818383815036a0 Reviewed-by: Sergio Ahumada --- tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp index 1eccdd768b..1030f0cfbd 100644 --- a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp +++ b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp @@ -633,7 +633,7 @@ void tst_QPushButton::sizeHint() tabWidget->addTab(tab2, "2"); QVBoxLayout *mainLayout = new QVBoxLayout(dialog); mainLayout->addWidget(tabWidget); - dialog->show(); + dialog->showNormal(); tabWidget->setCurrentWidget(tab2); tabWidget->setCurrentWidget(tab1); QTest::qWait(100); -- cgit v1.2.3 From cc5bd471636e25b641444be3d478c9f624022c64 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 2 Apr 2014 15:41:00 +0200 Subject: Fix the QGridLayout autotest One issue was that the text of a QPushButton would stretch the widget if the platform font is to big. The other issue was that the autotest did not expect that show might translate to a showFullScreen on some platforms. Change-Id: I3a9903979d766d04c402fda309d0492cfa506ed6 Reviewed-by: Sergio Ahumada --- tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp index 1003a9fb1f..3b7c2ac14d 100644 --- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp +++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp @@ -713,7 +713,7 @@ void tst_QGridLayout::spacingsAndMargins() grid1.setColumnStretch(columns-1, 1); grid1.setRowStretch(rows-1, 1); - toplevel.show(); + toplevel.showNormal(); toplevel.adjustSize(); QApplication::processEvents(); QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); @@ -1230,6 +1230,9 @@ void tst_QGridLayout::layoutSpacing_data() style->reimplementSubelementRect = true; QApplication::setStyle(style); QWidget *w = new QWidget(); + QFont font; + font.setPixelSize(10); + w->setFont(font); setFrameless(w); QGridLayout *layout = new QGridLayout(); QPushButton *pb1 = new QPushButton(QLatin1String("Push 1"), w); -- cgit v1.2.3 From e39f30a0d27608cf112f818f2c63418bfeb93cb3 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 2 Apr 2014 17:28:52 +0200 Subject: Fix QTabBar autotest for high DPI displays Change-Id: Ic50d7fb9eb3568f16dd1422c380a4ae7bb288a51 Reviewed-by: Sergio Ahumada --- tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp index 0dac7d85e4..345b8d82ad 100644 --- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp @@ -316,12 +316,17 @@ void tst_QTabBar::sizeHints() tabBar.setUsesScrollButtons(false); tabBar.setElideMode(Qt::ElideRight); // qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); - QVERIFY(tabBar.minimumSizeHint().width() < 500); - QVERIFY(tabBar.sizeHint().width() > 700); // unchanged + + // The sizeHint is very much dependent on the screen DPI value + // so we can not really predict it. + int tabBarMinSizeHintWidth = tabBar.minimumSizeHint().width(); + int tabBarSizeHintWidth = tabBar.sizeHint().width(); + QVERIFY(tabBarMinSizeHintWidth < tabBarSizeHintWidth); + QVERIFY(tabBarSizeHintWidth > 700); // unchanged tabBar.addTab("This is tab10 with a very long title"); - QVERIFY(tabBar.minimumSizeHint().width() < 600); - QVERIFY(tabBar.sizeHint().width() > 700); // unchanged + QVERIFY(tabBar.minimumSizeHint().width() > tabBarMinSizeHintWidth); + QVERIFY(tabBar.sizeHint().width() > tabBarSizeHintWidth); } void tst_QTabBar::setUsesScrollButtons_data() -- cgit v1.2.3 From 581d10bdf26dacaa36a916744ff5b43ecaa05f77 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 1 Apr 2014 14:18:15 +0200 Subject: Avoid recreating the underlying context in QGLContext wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QGLContexts created from a QOpenGLContext get their valid flag reset, resulting in creating a totally new underlying context. This is wrong and becomes visible when sharing is expected between contexts (since the QGLContext's underlying QOpenGLContext will not have sharing). Task-number: QTBUG-37893 Change-Id: I8cb37c11dfb400a77e510bf4c8219bedc742309e Reviewed-by: Jørgen Lind --- src/opengl/qgl.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 637cfc55a8..3cfdcc549c 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2934,8 +2934,9 @@ void QGLContext::setFormat(const QGLFormat &format) void QGLContext::setDevice(QPaintDevice *pDev) { Q_D(QGLContext); - if (isValid()) - reset(); + // Do not touch the valid flag here. The context is either a new one and + // valid is not yet set or it is adapted from a valid QOpenGLContext in which + // case it must remain valid. d->paintDevice = pDev; if (d->paintDevice && (d->paintDevice->devType() != QInternal::Widget && d->paintDevice->devType() != QInternal::Pixmap -- cgit v1.2.3 From bfee43349f47ec948b7e25165d76af45bb0ec588 Mon Sep 17 00:00:00 2001 From: Wolfgang Bremer Date: Wed, 2 Apr 2014 11:54:36 +0200 Subject: Fixes related to evdev in the configure script This adds evdev to the help, configure status output and will include it in the qconfig.h. Change-Id: Ibc07516ab07e7c53ec89b167d604f5cefa2d92b7 Reviewed-by: Fabian Bumberger Reviewed-by: Oswald Buddenhagen --- configure | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure b/configure index 72679947be..01c00964ef 100755 --- a/configure +++ b/configure @@ -2416,6 +2416,9 @@ Additional options: -no-iconv .......... Do not compile support for iconv(3). * -iconv ............. Compile support for iconv(3). + -no-evdev .......... Do not compile support for evdev. + * -evdev ............. Compile support for evdev. + -no-icu ............ Do not compile support for ICU libraries. + -icu ............... Compile support for ICU libraries. @@ -6045,6 +6048,7 @@ QMakeVar set sql-plugins "$SQL_PLUGINS" # X11/Unix/Mac only configs [ "$CFG_CUPS" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CUPS" [ "$CFG_ICONV" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_ICONV" +[ "$CFG_EVDEV" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EVDEV" [ "$CFG_GLIB" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_GLIB" [ "$CFG_QGTKSTYLE" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_STYLE_GTK" [ "$CFG_CLOCK_MONOTONIC" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CLOCK_MONOTONIC" @@ -6464,6 +6468,7 @@ report_support " ALSA ..................." "$CFG_ALSA" report_support " CUPS ..................." "$CFG_CUPS" [ "$XPLATFORM_MINGW" = "yes" ] && \ report_support " DirectWrite ............" "$CFG_DIRECTWRITE" +report_support " Evdev .................." "$CFG_EVDEV" report_support " FontConfig ............." "$CFG_FONTCONFIG" report_support " FreeType ..............." "$CFG_FREETYPE" system "system library" yes "bundled copy" report_support " Glib ..................." "$CFG_GLIB" -- cgit v1.2.3 From bc4590a780a59d9317d1ddcc7b8936f0847310bf Mon Sep 17 00:00:00 2001 From: Wolfgang Bremer Date: Tue, 1 Apr 2014 14:28:12 +0200 Subject: BlackBerry,QNX: Switch to QMAKE_PLATFORM from CONFIG This is the right configuration of the platform within the mkspecs. It enables the usage of additional features like the automatic detection of platform specific prf files. Change-Id: I2f19265d283e47c62455128f217bc44ba88cdc98 Reviewed-by: Sergio Ahumada Reviewed-by: Oswald Buddenhagen --- mkspecs/blackberry-armle-v7-qcc/qmake.conf | 2 +- mkspecs/blackberry-x86-qcc/qmake.conf | 2 +- mkspecs/common/qcc-base-qnx.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mkspecs/blackberry-armle-v7-qcc/qmake.conf b/mkspecs/blackberry-armle-v7-qcc/qmake.conf index 2e24e4e0d3..2fb367b8a4 100644 --- a/mkspecs/blackberry-armle-v7-qcc/qmake.conf +++ b/mkspecs/blackberry-armle-v7-qcc/qmake.conf @@ -5,7 +5,7 @@ load(qt_config) DEFINES += Q_OS_BLACKBERRY -CONFIG += blackberry +QMAKE_PLATFORM += blackberry LIBS += -lbps # Blackberry also has support for stack smashing protection in its libc diff --git a/mkspecs/blackberry-x86-qcc/qmake.conf b/mkspecs/blackberry-x86-qcc/qmake.conf index d2c6b3c9e9..c0561694cb 100644 --- a/mkspecs/blackberry-x86-qcc/qmake.conf +++ b/mkspecs/blackberry-x86-qcc/qmake.conf @@ -5,7 +5,7 @@ load(qt_config) DEFINES += Q_OS_BLACKBERRY -CONFIG += blackberry +QMAKE_PLATFORM += blackberry LIBS += -lbps # Blackberry also has support for stack smashing protection in its libc diff --git a/mkspecs/common/qcc-base-qnx.conf b/mkspecs/common/qcc-base-qnx.conf index d28fe1fc63..e08ac9621e 100644 --- a/mkspecs/common/qcc-base-qnx.conf +++ b/mkspecs/common/qcc-base-qnx.conf @@ -4,7 +4,7 @@ include(qcc-base.conf) -CONFIG += qnx +QMAKE_PLATFORM += qnx #Choose qnx QPA Plugin as default QT_QPA_DEFAULT_PLATFORM = qnx -- cgit v1.2.3 From 151cf2047aa36ac395a841a3ced8b2142a997aec Mon Sep 17 00:00:00 2001 From: Wolfgang Bremer Date: Wed, 2 Apr 2014 11:54:36 +0200 Subject: Fix cross platform detection of evdev on win32 Evdev is not known to the windows configure and therefore some code is currently broken which depends on QT_NO_EVDEV. This patch introduces evdev to the configure app on windows and disables evdev support for cross compilation if not available. Change-Id: I6acb5b593668c85a19ef8658a8d4c36ec3d2a686 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 9cebe6682b..176fe3092f 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -190,6 +190,7 @@ Configure::Configure(int& argc, char** argv) dictionary[ "POSIX_IPC" ] = "no"; dictionary[ "QT_GLIB" ] = "no"; dictionary[ "QT_ICONV" ] = "auto"; + dictionary[ "QT_EVDEV" ] = "auto"; dictionary[ "QT_INOTIFY" ] = "auto"; dictionary[ "QT_EVENTFD" ] = "auto"; dictionary[ "QT_CUPS" ] = "auto"; @@ -1255,6 +1256,12 @@ void Configure::parseCmdLine() dictionary["QT_ICONV"] = "gnu"; } + else if (configCmdLine.at(i) == "-no-evdev") { + dictionary[ "QT_EVDEV" ] = "no"; + } else if (configCmdLine.at(i) == "-evdev") { + dictionary[ "QT_EVDEV" ] = "yes"; + } + else if (configCmdLine.at(i) == "-inotify") { dictionary["QT_INOTIFY"] = "yes"; } else if (configCmdLine.at(i) == "-no-inotify") { @@ -1668,6 +1675,7 @@ void Configure::applySpecSpecifics() dictionary[ "QT_CUPS" ] = "no"; dictionary[ "QT_GLIB" ] = "no"; dictionary[ "QT_ICONV" ] = "no"; + dictionary[ "QT_EVDEV" ] = "no"; dictionary[ "FONT_CONFIG" ] = "auto"; dictionary["DECORATIONS"] = "default windows styled"; @@ -1826,6 +1834,9 @@ bool Configure::displayHelp() desc("QT_ICONV", "yes", "-sun-iconv", "Enable support for iconv(3) using sun-iconv."); desc("QT_ICONV", "yes", "-gnu-iconv", "Enable support for iconv(3) using gnu-libiconv.\n"); + desc("QT_EVDEV", "no", "-no-evdev", "Do not enable support for evdev."); + desc("QT_EVDEV", "yes", "-evdev", "Enable support for evdev."); + desc("QT_INOTIFY", "yes", "-inotify", "Explicitly enable Qt inotify(7) support."); desc("QT_INOTIFY", "no", "-no-inotify", "Explicitly disable Qt inotify(7) support.\n"); @@ -2237,6 +2248,8 @@ bool Configure::checkAvailability(const QString &part) available = tryCompileProject("qpa/direct2d"); } else if (part == "ICONV") { available = tryCompileProject("unix/iconv") || tryCompileProject("unix/gnu-libiconv"); + } else if (part == "EVDEV") { + available = tryCompileProject("unix/evdev"); } else if (part == "INOTIFY") { available = tryCompileProject("unix/inotify"); } else if (part == "QT_EVENTFD") { @@ -2387,6 +2400,10 @@ void Configure::autoDetection() if (dictionary["QT_ICONV"] == "auto") dictionary["QT_ICONV"] = checkAvailability("ICONV") ? "yes" : "no"; + // Detection of evdev support + if (dictionary["QT_EVDEV"] == "auto") + dictionary["QT_EVDEV"] = checkAvailability("EVDEV") ? "yes" : "no"; + // Detection of inotify if (dictionary["QT_INOTIFY"] == "auto") dictionary["QT_INOTIFY"] = checkAvailability("INOTIFY") ? "yes" : "no"; @@ -2805,6 +2822,9 @@ void Configure::generateOutputVars() else if (dictionary["QT_ICONV"] == "gnu") qtConfig += "gnu-libiconv"; + if (dictionary["QT_EVDEV"] == "yes") + qtConfig += "evdev"; + if (dictionary["QT_INOTIFY"] == "yes") qtConfig += "inotify"; @@ -3487,6 +3507,7 @@ void Configure::generateConfigfiles() if (dictionary["LARGE_FILE"] == "yes") qconfigList += "QT_LARGEFILE_SUPPORT=64"; if (dictionary["QT_CUPS"] == "no") qconfigList += "QT_NO_CUPS"; if (dictionary["QT_ICONV"] == "no") qconfigList += "QT_NO_ICONV"; + if (dictionary["QT_EVDEV"] == "no") qconfigList += "QT_NO_EVDEV"; if (dictionary["QT_GLIB"] == "no") qconfigList += "QT_NO_GLIB"; if (dictionary["QT_INOTIFY"] == "no") qconfigList += "QT_NO_INOTIFY"; if (dictionary["QT_EVENTFD"] == "no") qconfigList += "QT_NO_EVENTFD"; @@ -3583,6 +3604,7 @@ void Configure::displayConfig() sout << "Large File support.........." << dictionary[ "LARGE_FILE" ] << endl; sout << "NIS support................." << dictionary[ "NIS" ] << endl; sout << "Iconv support..............." << dictionary[ "QT_ICONV" ] << endl; + sout << "Evdev support..............." << dictionary[ "QT_EVDEV" ] << endl; sout << "Inotify support............." << dictionary[ "QT_INOTIFY" ] << endl; sout << "eventfd(7) support.........." << dictionary[ "QT_EVENTFD" ] << endl; sout << "Glib support................" << dictionary[ "QT_GLIB" ] << endl; -- cgit v1.2.3 From bd40a7cc446cafb8c9922d7d19845da580868859 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 28 Mar 2014 16:22:14 +0100 Subject: Update bundled libxkbcommon version to 0.4.1 This is the latest version, released on Mar 27 2014. It includes: https://bugs.freedesktop.org/show_bug.cgi?id=75798 https://bugs.freedesktop.org/show_bug.cgi?id=75892 Required for fixing input when running Qt application on Mac OS X with XQuartz and for fixing QTBUG-36281. Change-Id: Idc4d3c99a4008a10b91ab51c8910b36909974703 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- configure | 5 +- src/3rdparty/xkbcommon.pri | 5 +- src/3rdparty/xkbcommon/NEWS | 43 ++ src/3rdparty/xkbcommon/README | 114 ----- src/3rdparty/xkbcommon/README.md | 109 +++++ src/3rdparty/xkbcommon/src/context-priv.c | 41 +- src/3rdparty/xkbcommon/src/context.c | 6 +- src/3rdparty/xkbcommon/src/context.h | 17 +- src/3rdparty/xkbcommon/src/darray.h | 250 ++--------- src/3rdparty/xkbcommon/src/keymap-priv.c | 16 +- src/3rdparty/xkbcommon/src/keymap.h | 6 +- src/3rdparty/xkbcommon/src/keysym-utf.c | 48 +-- src/3rdparty/xkbcommon/src/keysym.c | 6 +- src/3rdparty/xkbcommon/src/scanner-utils.h | 159 +++++++ src/3rdparty/xkbcommon/src/state.c | 308 +++++++++++--- src/3rdparty/xkbcommon/src/text.c | 14 +- src/3rdparty/xkbcommon/src/utf8.c | 142 +++++++ src/3rdparty/xkbcommon/src/utf8.h | 36 ++ src/3rdparty/xkbcommon/src/utils.h | 22 +- src/3rdparty/xkbcommon/src/x11/x11-keymap.c | 73 ++-- src/3rdparty/xkbcommon/src/x11/x11-priv.h | 2 +- src/3rdparty/xkbcommon/src/xkb-keymap.c | 33 +- src/3rdparty/xkbcommon/src/xkbcomp/action.c | 427 ++++++++----------- src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c | 59 ++- src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h | 10 +- src/3rdparty/xkbcommon/src/xkbcomp/ast.h | 10 +- src/3rdparty/xkbcommon/src/xkbcomp/compat.c | 203 +-------- src/3rdparty/xkbcommon/src/xkbcomp/expr.c | 12 +- src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c | 81 +--- src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c | 91 ++-- src/3rdparty/xkbcommon/src/xkbcomp/keymap.c | 8 +- src/3rdparty/xkbcommon/src/xkbcomp/keywords.c | 5 +- src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h | 12 +- src/3rdparty/xkbcommon/src/xkbcomp/parser.c | 472 +++++++++++---------- src/3rdparty/xkbcommon/src/xkbcomp/parser.h | 2 +- src/3rdparty/xkbcommon/src/xkbcomp/rules.c | 259 ++++------- src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h | 145 ------- src/3rdparty/xkbcommon/src/xkbcomp/scanner.c | 54 +-- src/3rdparty/xkbcommon/src/xkbcomp/symbols.c | 129 +++--- src/3rdparty/xkbcommon/src/xkbcomp/types.c | 121 +----- src/3rdparty/xkbcommon/src/xkbcomp/vmod.c | 63 ++- src/3rdparty/xkbcommon/src/xkbcomp/vmod.h | 3 +- .../xkbcommon/xkbcommon/xkbcommon-compat.h | 4 + src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h | 8 + src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h | 140 +++++- src/plugins/platforms/xcb/qxcbkeyboard.h | 3 - 46 files changed, 1791 insertions(+), 1985 deletions(-) delete mode 100644 src/3rdparty/xkbcommon/README create mode 100644 src/3rdparty/xkbcommon/README.md create mode 100644 src/3rdparty/xkbcommon/src/scanner-utils.h create mode 100644 src/3rdparty/xkbcommon/src/utf8.c create mode 100644 src/3rdparty/xkbcommon/src/utf8.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h diff --git a/configure b/configure index 01c00964ef..d63baad87a 100755 --- a/configure +++ b/configure @@ -5053,11 +5053,12 @@ if [ "$CFG_KMS" != "no" ]; then fi # Detect libxkbcommon +MIN_REQ_XKBCOMMON="0.4.1" ORIG_CFG_XKBCOMMON="$CFG_XKBCOMMON" # currently only xcb platform plugin supports building xkbcommon if [ "$CFG_XCB" != "no" ]; then if [ "$CFG_XKBCOMMON" = "auto" ] || [ "$CFG_XKBCOMMON" = "system" ]; then - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xkbcommon xkbcommon-x11 >= 0.4.0" 2>/dev/null; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xkbcommon xkbcommon-x11 >= $MIN_REQ_XKBCOMMON" 2>/dev/null; then QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon xkbcommon-x11 2>/dev/null`" QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon xkbcommon-x11 2>/dev/null`" @@ -6564,7 +6565,7 @@ if [ "$CFG_OPENSSL" = "linked" ] && [ "$OPENSSL_LIBS" = "" ]; then echo fi if [ "$ORIG_CFG_XKBCOMMON" != qt ] && [ "$CFG_XKBCOMMON" = qt ]; then - echo "NOTE: libxkbcommon and libxkbcommon-x11 0.4.0 or higher not found on the system, will use " + echo "NOTE: libxkbcommon and libxkbcommon-x11 $MIN_REQ_XKBCOMMON or higher not found on the system, will use " echo "the bundled version from 3rd party directory." fi if [ "$CFG_XKBCOMMON" = "qt" ] && [ "$CFG_XKB_CONFIG_ROOT" = "not found" ]; then diff --git a/src/3rdparty/xkbcommon.pri b/src/3rdparty/xkbcommon.pri index eb34403746..eaef4749db 100644 --- a/src/3rdparty/xkbcommon.pri +++ b/src/3rdparty/xkbcommon.pri @@ -26,7 +26,8 @@ SOURCES += \ $$PWD/xkbcommon/src/text.c \ $$PWD/xkbcommon/src/context-priv.c \ $$PWD/xkbcommon/src/keymap-priv.c \ - $$PWD/xkbcommon/src/utils.c + $$PWD/xkbcommon/src/utils.c \ + $$PWD/xkbcommon/src/utf8.c SOURCES += \ $$PWD/xkbcommon/src/xkbcomp/action.c \ @@ -54,7 +55,7 @@ SOURCES += \ SOURCES += \ $$PWD/xkbcommon/src/x11/util.c \ $$PWD/xkbcommon/src/x11/x11-keymap.c \ # renamed: keymap.c -> x11-keymap.c - $$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-keymap.c + $$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-state.c } TR_EXCLUDE += $$PWD/* diff --git a/src/3rdparty/xkbcommon/NEWS b/src/3rdparty/xkbcommon/NEWS index 450b7535ee..07ebdd97e3 100644 --- a/src/3rdparty/xkbcommon/NEWS +++ b/src/3rdparty/xkbcommon/NEWS @@ -1,3 +1,46 @@ +libxkbcommon 0.4.1 +================== + +- Converted README to markdown and added a Quick Guide to the + documentation, which breezes through the most common parts of + xkbcommon. + +- Added two new functions, xkb_state_key_get_utf{8,32}(). They + combine the operations of xkb_state_key_get_syms() and + xkb_keysym_to_utf{8,32}(), and provide a nicer interface for it + (espcially for multiple-keysyms-per-level). + +- The xkb_state_key_get_utf{8,32}() functions now apply Control + transformation: when the Control modifier is active, the string + is converted to an appropriate control character. + This matches the behavior of libX11's XLookupString(3), and + required by the XKB specification: + http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier + + https://bugs.freedesktop.org/show_bug.cgi?id=75892 + +- The consumed modifiers for a key are now calculated similarly + to libX11. The previous behavior caused a bug where Shift would + not cancel an active Caps Lock. + +- Make xkbcommon-x11 work with the keymap reported by the XQuartz + X server. + + https://bugs.freedesktop.org/show_bug.cgi?id=75798 + +- Reduce memory usage during keymap compilation some more. + +- New API: + xkb_state_key_get_consumed_mods() + xkb_state_key_get_utf8() + xkb_state_key_get_utf32() + +- Deprecated API: + XKB_MAP_COMPILE_PLACEHOLDER, XKB_MAP_NO_FLAGS + use XKB_KEYMAP_NO_FLAGS instead. + +- Bug fixes. + libxkbcommon 0.4.0 ================== diff --git a/src/3rdparty/xkbcommon/README b/src/3rdparty/xkbcommon/README deleted file mode 100644 index 6b99c46620..0000000000 --- a/src/3rdparty/xkbcommon/README +++ /dev/null @@ -1,114 +0,0 @@ -Overview {#mainpage} -======== - -xkbcommon is a keymap compiler and support library which processes a -reduced subset of keymaps as defined by the XKB specification. Primarily, -a keymap is created from a set of Rules/Model/Layout/Variant/Options names, -processed through an XKB ruleset, and compiled into a struct xkb_keymap, -which is the base type for all xkbcommon operations. - -From an xkb_keymap, an xkb_state object is created which holds the current -state of all modifiers, groups, LEDs, etc, relating to that keymap. All -key events must be fed into the xkb_state object using xkb_state_update_key(). -Once this is done, the xkb_state object will be properly updated, and the -keysyms to use can be obtained with xkb_state_key_get_syms(). - -libxkbcommon does not distribute a dataset itself, other than for testing -purposes. The most common dataset is xkeyboard-config, as used by all -current distributions for their X11 XKB data. More information on -xkeyboard-config is available here: - http://www.freedesktop.org/wiki/Software/XKeyboardConfig - - -API -=== - -While xkbcommon's API is somewhat derived from the classic XKB API as found -in and friends, it has been substantially reworked to -expose fewer internal details to clients. The supported API is available -in the files. Additional support is provided for -X11 (XCB) clients, in the xkbcommon-x11 library, . - -The xkbcommon API and ABI are stable. We will attempt to not break ABI during -a minor release series, so applications written against 0.1.0 should be -completely compatible with 0.5.3, but not necessarily with 1.0.0. However, new -symbols may be introduced in any release. Thus, anyone packaging xkbcommon -should make sure any package depending on it depends on a release greater than -or equal to the version it was built against (or earlier, if it doesn't use -any newly-introduced symbols), but less than the next major release. - - -Relation to X11 -=============== - -Relative to the XKB 1.1 specification implemented in current X servers, -xkbcommon has removed support for some parts of the specification which -introduced unnecessary complications. Many of these removals were in fact -not implemented, or half-implemented at best, as well as being totally -unused in the standard dataset. - -Notable removals: - - geometry support - + there were very few geometry definitions available, and while - xkbcommon was responsible for parsing this insanely complex format, - it never actually did anything with it - + hopefully someone will develop a companion library which supports - keyboard geometries in a more useful format - - KcCGST (keycodes/compat/geometry/symbols/types) API - + use RMLVO instead; KcCGST is now an implementation detail - + including pre-defined keymap files - - XKM support - + may come in an optional X11 support/compatibility library - - around half of the interpret actions - + pointer device, message and redirect actions in particular - - non-virtual modifiers - + core and virtual modifiers have been collapsed into the same - namespace, with a 'significant' flag that largely parallels the - core/virtual split - - radio groups - + completely unused in current keymaps, never fully implemented - - overlays - + almost completely unused in current keymaps - - key behaviors - + used to implement radio groups and overlays, and to deal with things - like keys that physically lock; unused in current keymaps - - indicator behaviours such as LED-controls-key - + the only supported LED behaviour is key-controls-LED; again this - was never really used in current keymaps - -Notable additions: - - 32-bit keycodes - - extended number of modifiers - - extended number of groups - - multiple keysyms per level - + this requires incompatible dataset changes, such that X11 would - not be able to parse these - - -Development -=========== - -An extremely rudimentary homepage can be found at: - http://xkbcommon.org - -xkbcommon is maintained in git at github.com: - https://github.com/xkbcommon/libxkbcommon - -Patches are always welcome, and may be sent to either xorg-devel@lists.x.org, -or wayland-devel@lists.freedesktop.org. - -Bugs are tracked in Bugzilla at: - https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon -Or in github at: - https://github.com/xkbcommon/libxkbcommon/issues - -The maintainers are Daniel Stone and Ran Benita, who can be reached at: - - - - -Credits -======= - -Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon -off the ground initially. diff --git a/src/3rdparty/xkbcommon/README.md b/src/3rdparty/xkbcommon/README.md new file mode 100644 index 0000000000..2627a324a6 --- /dev/null +++ b/src/3rdparty/xkbcommon/README.md @@ -0,0 +1,109 @@ +# libxkbcommon + +xkbcommon is a keymap compiler and support library which processes a +reduced subset of keymaps as defined by the XKB specification. Primarily, +a keymap is created from a set of Rules/Model/Layout/Variant/Options names, +processed through an XKB ruleset, and compiled into a struct xkb_keymap, +which is the base type for all xkbcommon operations. + +From an xkb_keymap, an xkb_state object is created which holds the current +state of all modifiers, groups, LEDs, etc, relating to that keymap. All +key events must be fed into the xkb_state object using xkb_state_update_key(). +Once this is done, the xkb_state object will be properly updated, and the +keysyms to use can be obtained with xkb_state_key_get_syms(). + +libxkbcommon does not distribute a dataset itself, other than for testing +purposes. The most common dataset is xkeyboard-config, as used by all +current distributions for their X11 XKB data. More information on +xkeyboard-config is available here: + http://www.freedesktop.org/wiki/Software/XKeyboardConfig + +## Quick Guide + +See [Quick Guide](doc/quick-guide.md). + +## API + +While xkbcommon's API is somewhat derived from the classic XKB API as found +in X11/extensions/XKB.h and friends, it has been substantially reworked to +expose fewer internal details to clients. The supported API is available +in the xkbcommon/xkbcommon-*.h files. Additional support is provided for +X11 (XCB) clients, in the xkbcommon-x11 library, xkbcommon/xkbcommon-x11.h. + +The xkbcommon API and ABI are stable. We will attempt to not break ABI during +a minor release series, so applications written against 0.1.0 should be +completely compatible with 0.5.3, but not necessarily with 1.0.0. However, new +symbols may be introduced in any release. Thus, anyone packaging xkbcommon +should make sure any package depending on it depends on a release greater than +or equal to the version it was built against (or earlier, if it doesn't use +any newly-introduced symbols), but less than the next major release. + +## Relation to X11 + +Relative to the XKB 1.1 specification implemented in current X servers, +xkbcommon has removed support for some parts of the specification which +introduced unnecessary complications. Many of these removals were in fact +not implemented, or half-implemented at best, as well as being totally +unused in the standard dataset. + +Notable removals: +- geometry support + + there were very few geometry definitions available, and while + xkbcommon was responsible for parsing this insanely complex format, + it never actually did anything with it + + hopefully someone will develop a companion library which supports + keyboard geometries in a more useful format +- KcCGST (keycodes/compat/geometry/symbols/types) API + + use RMLVO instead; KcCGST is now an implementation detail + + including pre-defined keymap files +- XKM support + + may come in an optional X11 support/compatibility library +- around half of the interpret actions + + pointer device, message and redirect actions in particular +- non-virtual modifiers + + core and virtual modifiers have been collapsed into the same + namespace, with a 'significant' flag that largely parallels the + core/virtual split +- radio groups + + completely unused in current keymaps, never fully implemented +- overlays + + almost completely unused in current keymaps +- key behaviors + + used to implement radio groups and overlays, and to deal with things + like keys that physically lock; unused in current keymaps +- indicator behaviours such as LED-controls-key + + the only supported LED behaviour is key-controls-LED; again this + was never really used in current keymaps + +Notable additions: +- 32-bit keycodes +- extended number of modifiers +- extended number of groups +- multiple keysyms per level + + this requires incompatible dataset changes, such that X11 would + not be able to parse these + +## Development + +An extremely rudimentary homepage can be found at + http://xkbcommon.org + +xkbcommon is maintained in git at + https://github.com/xkbcommon/libxkbcommon + +Patches are always welcome, and may be sent to either + or + +Bugs are also welcome, and may be reported either at + Bugzilla https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon +or + Github https://github.com/xkbcommon/libxkbcommon/issues + +The maintainers are +- Daniel Stone +- Ran Benita + +## Credits + +Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon +off the ground initially. diff --git a/src/3rdparty/xkbcommon/src/context-priv.c b/src/3rdparty/xkbcommon/src/context-priv.c index 4d7b2ed110..c934201685 100644 --- a/src/3rdparty/xkbcommon/src/context-priv.c +++ b/src/3rdparty/xkbcommon/src/context-priv.c @@ -112,60 +112,79 @@ xkb_context_get_buffer(struct xkb_context *ctx, size_t size) #define DEFAULT_XKB_OPTIONS NULL #endif -const char * +static const char * xkb_context_get_default_rules(struct xkb_context *ctx) { const char *env = NULL; if (ctx->use_environment_names) - env = getenv("XKB_DEFAULT_RULES"); + env = secure_getenv("XKB_DEFAULT_RULES"); return env ? env : DEFAULT_XKB_RULES; } -const char * +static const char * xkb_context_get_default_model(struct xkb_context *ctx) { const char *env = NULL; if (ctx->use_environment_names) - env = getenv("XKB_DEFAULT_MODEL"); + env = secure_getenv("XKB_DEFAULT_MODEL"); return env ? env : DEFAULT_XKB_MODEL; } -const char * +static const char * xkb_context_get_default_layout(struct xkb_context *ctx) { const char *env = NULL; if (ctx->use_environment_names) - env = getenv("XKB_DEFAULT_LAYOUT"); + env = secure_getenv("XKB_DEFAULT_LAYOUT"); return env ? env : DEFAULT_XKB_LAYOUT; } -const char * +static const char * xkb_context_get_default_variant(struct xkb_context *ctx) { const char *env = NULL; - const char *layout = getenv("XKB_DEFAULT_VARIANT"); + const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT"); /* We don't want to inherit the variant if they haven't also set a * layout, since they're so closely paired. */ if (layout && ctx->use_environment_names) - env = getenv("XKB_DEFAULT_VARIANT"); + env = secure_getenv("XKB_DEFAULT_VARIANT"); return env ? env : DEFAULT_XKB_VARIANT; } -const char * +static const char * xkb_context_get_default_options(struct xkb_context *ctx) { const char *env = NULL; if (ctx->use_environment_names) - env = getenv("XKB_DEFAULT_OPTIONS"); + env = secure_getenv("XKB_DEFAULT_OPTIONS"); return env ? env : DEFAULT_XKB_OPTIONS; } + +void +xkb_context_sanitize_rule_names(struct xkb_context *ctx, + struct xkb_rule_names *rmlvo) +{ + if (isempty(rmlvo->rules)) + rmlvo->rules = xkb_context_get_default_rules(ctx); + if (isempty(rmlvo->model)) + rmlvo->model = xkb_context_get_default_model(ctx); + /* Layout and variant are tied together, so don't try to use one from + * the caller and one from the environment. */ + if (isempty(rmlvo->layout)) { + rmlvo->layout = xkb_context_get_default_layout(ctx); + rmlvo->variant = xkb_context_get_default_variant(ctx); + } + /* Options can be empty, so respect that if passed in. */ + if (rmlvo->options == NULL) + rmlvo->options = xkb_context_get_default_options(ctx); +} diff --git a/src/3rdparty/xkbcommon/src/context.c b/src/3rdparty/xkbcommon/src/context.c index e64b91542f..e9c52ebeee 100644 --- a/src/3rdparty/xkbcommon/src/context.c +++ b/src/3rdparty/xkbcommon/src/context.c @@ -82,7 +82,7 @@ xkb_context_include_path_append_default(struct xkb_context *ctx) ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT); - home = getenv("HOME"); + home = secure_getenv("HOME"); if (!home) return ret; err = asprintf(&user_path, "%s/.xkb", home); @@ -252,11 +252,11 @@ xkb_context_new(enum xkb_context_flags flags) ctx->log_verbosity = 0; /* Environment overwrites defaults. */ - env = getenv("XKB_LOG_LEVEL"); + env = secure_getenv("XKB_LOG_LEVEL"); if (env) xkb_context_set_log_level(ctx, log_level(env)); - env = getenv("XKB_LOG_VERBOSITY"); + env = secure_getenv("XKB_LOG_VERBOSITY"); if (env) xkb_context_set_log_verbosity(ctx, log_verbosity(env)); diff --git a/src/3rdparty/xkbcommon/src/context.h b/src/3rdparty/xkbcommon/src/context.h index 486f4085a6..03e6d50abb 100644 --- a/src/3rdparty/xkbcommon/src/context.h +++ b/src/3rdparty/xkbcommon/src/context.h @@ -91,20 +91,9 @@ ATTR_PRINTF(4, 5) void xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity, const char *fmt, ...); -const char * -xkb_context_get_default_rules(struct xkb_context *ctx); - -const char * -xkb_context_get_default_model(struct xkb_context *ctx); - -const char * -xkb_context_get_default_layout(struct xkb_context *ctx); - -const char * -xkb_context_get_default_variant(struct xkb_context *ctx); - -const char * -xkb_context_get_default_options(struct xkb_context *ctx); +void +xkb_context_sanitize_rule_names(struct xkb_context *ctx, + struct xkb_rule_names *rmlvo); /* * The format is not part of the argument list in order to avoid the diff --git a/src/3rdparty/xkbcommon/src/darray.h b/src/3rdparty/xkbcommon/src/darray.h index 0cf3747be7..d3fe37b089 100644 --- a/src/3rdparty/xkbcommon/src/darray.h +++ b/src/3rdparty/xkbcommon/src/darray.h @@ -23,93 +23,15 @@ #ifndef CCAN_DARRAY_H #define CCAN_DARRAY_H +/* Originally taken from: http://ccodearchive.net/info/darray.html + * But modified for libxkbcommon. */ + #include #include +#include +#include -/* - * SYNOPSIS - * - * Life cycle of a darray (dynamically-allocated array): - * - * darray(int) a = darray_new(); - * darray_free(a); - * - * struct {darray(int) a;} foo; - * darray_init(foo.a); - * darray_free(foo.a); - * - * Typedefs for darrays of common types: - * - * darray_char, darray_schar, darray_uchar - * darray_short, darray_int, darray_long - * darray_ushort, darray_uint, darray_ulong - * - * Access: - * - * T darray_item(darray(T) arr, size_t index); - * size_t darray_size(darray(T) arr); - * size_t darray_alloc(darray(T) arr); - * bool darray_empty(darray(T) arr); - * - * // Access raw memory, starting from the item in offset. - * // Not safe, be careful, etc. - * T* darray_mem(darray(T) arr, size_t offset); - * - * Insertion (single item): - * - * void darray_append(darray(T) arr, T item); - * void darray_prepend(darray(T) arr, T item); - * void darray_push(darray(T) arr, T item); // same as darray_append - * - * Insertion (multiple items): - * - * void darray_append_items(darray(T) arr, T *items, size_t count); - * void darray_prepend_items(darray(T) arr, T *items, size_t count); - * - * void darray_appends(darray(T) arr, [T item, [...]]); - * void darray_prepends(darray(T) arr, [T item, [...]]); - * - * Removal: - * - * T darray_pop(darray(T) arr | darray_size(arr) != 0); - * T* darray_pop_check(darray(T*) arr); - * - * Replacement: - * - * void darray_from_items(darray(T) arr, T *items, size_t count); - * void darray_from_c(darray(T) arr, T c_array[N]); - * - * String buffer: - * - * void darray_append_string(darray(char) arr, const char *str); - * void darray_append_lit(darray(char) arr, char stringLiteral[N+1]); - * - * void darray_prepend_string(darray(char) arr, const char *str); - * void darray_prepend_lit(darray(char) arr, char stringLiteral[N+1]); - * - * void darray_from_string(darray(T) arr, const char *str); - * void darray_from_lit(darray(char) arr, char stringLiteral[N+1]); - * - * Size management: - * - * void darray_resize(darray(T) arr, size_t newSize); - * void darray_resize0(darray(T) arr, size_t newSize); - * - * void darray_realloc(darray(T) arr, size_t newAlloc); - * void darray_growalloc(darray(T) arr, size_t newAlloc); - * - * Traversal: - * - * darray_foreach(T *&i, darray(T) arr) {...} - * darray_foreach_reverse(T *&i, darray(T) arr) {...} - * - * Except for darray_foreach and darray_foreach_reverse, - * all macros evaluate their non-darray arguments only once. - */ - -/*** Life cycle ***/ - -#define darray(type) struct { type *item; size_t size; size_t alloc; } +#define darray(type) struct { type *item; unsigned size; unsigned alloc; } #define darray_new() { 0, 0, 0 } @@ -118,7 +40,8 @@ } while (0) #define darray_free(arr) do { \ - free((arr).item); darray_init(arr); \ + free((arr).item); \ + darray_init(arr); \ } while (0) /* @@ -154,11 +77,8 @@ typedef darray (unsigned long) darray_ulong; #define darray_item(arr, i) ((arr).item[i]) #define darray_size(arr) ((arr).size) -#define darray_alloc(arr) ((arr).alloc) #define darray_empty(arr) ((arr).size == 0) - #define darray_mem(arr, offset) ((arr).item + (offset)) -#define darray_same(arr1, arr2) ((arr1).item == (arr2).item) /*** Insertion (single item) ***/ @@ -167,74 +87,20 @@ typedef darray (unsigned long) darray_ulong; (arr).item[(arr).size - 1] = (__VA_ARGS__); \ } while (0) -#define darray_prepend(arr, ...) do { \ - darray_resize(arr, (arr).size + 1); \ - memmove((arr).item + 1, (arr).item, \ - ((arr).size - 1) * sizeof(*(arr).item)); \ - (arr).item[0] = (__VA_ARGS__); \ -} while (0) - -#define darray_push(arr, ...) darray_append(arr, __VA_ARGS__) - /*** Insertion (multiple items) ***/ #define darray_append_items(arr, items, count) do { \ - size_t __count = (count), __oldSize = (arr).size; \ + unsigned __count = (count), __oldSize = (arr).size; \ darray_resize(arr, __oldSize + __count); \ memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ } while (0) -#define darray_prepend_items(arr, items, count) do { \ - size_t __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __count + __oldSize); \ - memmove((arr).item + __count, (arr).item, \ - __oldSize * sizeof(*(arr).item)); \ - memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ -} while (0) - -#define darray_append_items_nullterminate(arr, items, count) do { \ - size_t __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __oldSize + __count + 1); \ - memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ - (arr).item[--(arr).size] = 0; \ -} while (0) - -#define darray_prepend_items_nullterminate(arr, items, count) do { \ - size_t __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __count + __oldSize + 1); \ - memmove((arr).item + __count, (arr).item, \ - __oldSize * sizeof(*(arr).item)); \ - memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ - (arr).item[--(arr).size] = 0; \ -} while (0) - -#define darray_appends_t(arr, type, ...) do { \ - type __src[] = { __VA_ARGS__ }; \ - darray_append_items(arr, __src, sizeof(__src) / sizeof(*__src)); \ -} while (0) - -#define darray_prepends_t(arr, type, ...) do { \ - type __src[] = { __VA_ARGS__ }; \ - darray_prepend_items(arr, __src, sizeof(__src) / sizeof(*__src)); \ -} while (0) - -/*** Removal ***/ - -/* Warning: Do not call darray_pop on an empty darray. */ -#define darray_pop(arr) ((arr).item[--(arr).size]) -#define darray_pop_check(arr) ((arr).size ? darray_pop(arr) : NULL) - -/*** Replacement ***/ - #define darray_from_items(arr, items, count) do { \ - size_t __count = (count); \ + unsigned __count = (count); \ darray_resize(arr, __count); \ memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ } while (0) -#define darray_from_c(arr, c_array) \ - darray_from_items(arr, c_array, sizeof(c_array) / sizeof(*(c_array))) - #define darray_copy(arr_to, arr_from) \ darray_from_items((arr_to), (arr_from).item, (arr_from).size) @@ -251,24 +117,20 @@ typedef darray (unsigned long) darray_ulong; (arr).size--; \ } while (0) -#define darray_prepend_string(arr, str) do { \ - const char *__str = (str); \ - darray_prepend_items_nullterminate(arr, __str, strlen(__str)); \ -} while (0) - -#define darray_prepend_lit(arr, stringLiteral) \ - darray_prepend_items_nullterminate(arr, stringLiteral, \ - sizeof(stringLiteral) - 1) - -#define darray_from_string(arr, str) do { \ - const char *__str = (str); \ - darray_from_items(arr, __str, strlen(__str) + 1); \ - (arr).size--; \ +#define darray_appends_nullterminate(arr, items, count) do { \ + unsigned __count = (count), __oldSize = (arr).size; \ + darray_resize(arr, __oldSize + __count + 1); \ + memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ + (arr).item[--(arr).size] = 0; \ } while (0) -#define darray_from_lit(arr, stringLiteral) do { \ - darray_from_items(arr, stringLiteral, sizeof(stringLiteral)); \ - (arr).size--; \ +#define darray_prepends_nullterminate(arr, items, count) do { \ + unsigned __count = (count), __oldSize = (arr).size; \ + darray_resize(arr, __count + __oldSize + 1); \ + memmove((arr).item + __count, (arr).item, \ + __oldSize * sizeof(*(arr).item)); \ + memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ + (arr).item[--(arr).size] = 0; \ } while (0) /*** Size management ***/ @@ -277,7 +139,7 @@ typedef darray (unsigned long) darray_ulong; darray_growalloc(arr, (arr).size = (newSize)) #define darray_resize0(arr, newSize) do { \ - size_t __oldSize = (arr).size, __newSize = (newSize); \ + unsigned __oldSize = (arr).size, __newSize = (newSize); \ (arr).size = __newSize; \ if (__newSize > __oldSize) { \ darray_growalloc(arr, __newSize); \ @@ -292,14 +154,16 @@ typedef darray (unsigned long) darray_ulong; } while (0) #define darray_growalloc(arr, need) do { \ - size_t __need = (need); \ + unsigned __need = (need); \ if (__need > (arr).alloc) \ - darray_realloc(arr, darray_next_alloc((arr).alloc, __need)); \ + darray_realloc(arr, darray_next_alloc((arr).alloc, __need, \ + sizeof(*(arr).item))); \ } while (0) -static inline size_t -darray_next_alloc(size_t alloc, size_t need) +static inline unsigned +darray_next_alloc(unsigned alloc, unsigned need, unsigned itemSize) { + assert(need < UINT_MAX / itemSize / 2); /* Overflow. */ if (alloc == 0) alloc = 4; while (alloc < need) @@ -309,11 +173,6 @@ darray_next_alloc(size_t alloc, size_t need) /*** Traversal ***/ -/* - * darray_foreach(T *&i, darray(T) arr) {...} - * - * Traverse a darray. `i` must be declared in advance as a pointer to an item. - */ #define darray_foreach(i, arr) \ for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++) @@ -331,58 +190,7 @@ darray_next_alloc(size_t alloc, size_t need) (idx) < (arr).size; \ (idx)++, (val)++) -/* - * darray_foreach_reverse(T *&i, darray(T) arr) {...} - * - * Like darray_foreach, but traverse in reverse order. - */ #define darray_foreach_reverse(i, arr) \ for ((i) = &(arr).item[(arr).size]; (i)-- > &(arr).item[0]; ) #endif /* CCAN_DARRAY_H */ - -/* - * - * darray_growalloc(arr, newAlloc) sees if the darray can currently hold newAlloc items; - * if not, it increases the alloc to satisfy this requirement, allocating slack - * space to avoid having to reallocate for every size increment. - * - * darray_from_string(arr, str) copies a string to an darray_char. - * - * darray_push(arr, item) pushes an item to the end of the darray. - * darray_pop(arr) pops it back out. Be sure there is at least one item in the darray before calling. - * darray_pop_check(arr) does the same as darray_pop, but returns NULL if there are no more items left in the darray. - * - * darray_make_room(arr, room) ensures there's 'room' elements of space after the end of the darray, and it returns a pointer to this space. - * Currently requires HAVE_STATEMENT_EXPR, but I plan to remove this dependency by creating an inline function. - * - * The following require HAVE_TYPEOF==1 : - * - * darray_appends(arr, item0, item1...) appends a collection of comma-delimited items to the darray. - * darray_prepends(arr, item0, item1...) prepends a collection of comma-delimited items to the darray.\ - * - * - * Examples: - * - * darray(int) arr; - * int *i; - * - * darray_appends(arr, 0,1,2,3,4); - * darray_appends(arr, -5,-4,-3,-2,-1); - * darray_foreach(i, arr) - * printf("%d ", *i); - * printf("\n"); - * - * darray_free(arr); - * - * - * typedef struct {int n,d;} Fraction; - * darray(Fraction) fractions; - * Fraction *i; - * - * darray_appends(fractions, {3,4}, {3,5}, {2,1}); - * darray_foreach(i, fractions) - * printf("%d/%d\n", i->n, i->d); - * - * darray_free(fractions); - */ diff --git a/src/3rdparty/xkbcommon/src/keymap-priv.c b/src/3rdparty/xkbcommon/src/keymap-priv.c index 9f42040828..2b3f8cde0c 100644 --- a/src/3rdparty/xkbcommon/src/keymap-priv.c +++ b/src/3rdparty/xkbcommon/src/keymap-priv.c @@ -30,12 +30,7 @@ static void update_builtin_keymap_fields(struct xkb_keymap *keymap) { struct xkb_context *ctx = keymap->ctx; - - /* - * Add predefined (AKA real, core, X11) modifiers. - * The order is important! - */ - darray_appends_t(keymap->mods, struct xkb_mod, + const struct xkb_mod builtin_mods[] = { { .name = xkb_atom_intern_literal(ctx, "Shift"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Lock"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Control"), .type = MOD_REAL }, @@ -43,7 +38,14 @@ update_builtin_keymap_fields(struct xkb_keymap *keymap) { .name = xkb_atom_intern_literal(ctx, "Mod2"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Mod3"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Mod4"), .type = MOD_REAL }, - { .name = xkb_atom_intern_literal(ctx, "Mod5"), .type = MOD_REAL }); + { .name = xkb_atom_intern_literal(ctx, "Mod5"), .type = MOD_REAL }, + }; + + /* + * Add predefined (AKA real, core, X11) modifiers. + * The order is important! + */ + darray_append_items(keymap->mods, builtin_mods, ARRAY_SIZE(builtin_mods)); } struct xkb_keymap * diff --git a/src/3rdparty/xkbcommon/src/keymap.h b/src/3rdparty/xkbcommon/src/keymap.h index 5f514ec779..39ac4209ae 100644 --- a/src/3rdparty/xkbcommon/src/keymap.h +++ b/src/3rdparty/xkbcommon/src/keymap.h @@ -146,7 +146,7 @@ enum xkb_action_flags { ACTION_ABSOLUTE_SWITCH = (1 << 5), ACTION_ABSOLUTE_X = (1 << 6), ACTION_ABSOLUTE_Y = (1 << 7), - ACTION_NO_ACCEL = (1 << 8), + ACTION_ACCEL = (1 << 8), ACTION_SAME_SCREEN = (1 << 9), }; @@ -223,7 +223,7 @@ struct xkb_pointer_button_action { enum xkb_action_type type; enum xkb_action_flags flags; uint8_t count; - int8_t button; + uint8_t button; }; struct xkb_private_action { @@ -262,10 +262,10 @@ struct xkb_key_type { struct xkb_sym_interpret { xkb_keysym_t sym; enum xkb_match_operation match; - bool level_one_only; xkb_mod_mask_t mods; xkb_mod_index_t virtual_mod; union xkb_action action; + bool level_one_only; bool repeat; }; diff --git a/src/3rdparty/xkbcommon/src/keysym-utf.c b/src/3rdparty/xkbcommon/src/keysym-utf.c index 129da15cf8..ffe2cea48e 100644 --- a/src/3rdparty/xkbcommon/src/keysym-utf.c +++ b/src/3rdparty/xkbcommon/src/keysym-utf.c @@ -37,6 +37,7 @@ #include "xkbcommon/xkbcommon.h" #include "utils.h" +#include "utf8.h" /* We don't use the uint32_t types here, to save some space. */ struct codepair { @@ -838,15 +839,15 @@ static const struct codepair keysymtab[] = { static uint32_t bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym) { - int first = 0; - int last = length; + size_t first = 0; + size_t last = length; if (keysym < table[0].keysym || keysym > table[length].keysym) return 0; /* binary search in table */ while (last >= first) { - int mid = (first + last) / 2; + size_t mid = (first + last) / 2; if (table[mid].keysym < keysym) first = mid + 1; else if (table[mid].keysym > keysym) @@ -912,47 +913,6 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym) * Author: Rob Bradford */ -static int -utf32_to_utf8(uint32_t unichar, char *buffer) -{ - int count, shift, length; - uint8_t head; - - if (unichar <= 0x007f) { - buffer[0] = unichar; - buffer[1] = '\0'; - return 2; - } - else if (unichar <= 0x07FF) { - length = 2; - head = 0xc0; - } - else if (unichar <= 0xffff) { - length = 3; - head = 0xe0; - } - else if (unichar <= 0x1fffff) { - length = 4; - head = 0xf0; - } - else if (unichar <= 0x3ffffff) { - length = 5; - head = 0xf8; - } - else { - length = 6; - head = 0xfc; - } - - for (count = length - 1, shift = 0; count > 0; count--, shift += 6) - buffer[count] = 0x80 | ((unichar >> shift) & 0x3f); - - buffer[0] = head | ((unichar >> shift) & 0x3f); - buffer[length] = '\0'; - - return length + 1; -} - XKB_EXPORT int xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size) { diff --git a/src/3rdparty/xkbcommon/src/keysym.c b/src/3rdparty/xkbcommon/src/keysym.c index f52d751973..e8fa5e12ba 100644 --- a/src/3rdparty/xkbcommon/src/keysym.c +++ b/src/3rdparty/xkbcommon/src/keysym.c @@ -64,7 +64,11 @@ compare_by_keysym(const void *a, const void *b) { const xkb_keysym_t *key = a; const struct name_keysym *entry = b; - return *key - (int32_t) entry->keysym; + if (*key < entry->keysym) + return -1; + if (*key > entry->keysym) + return 1; + return 0; } static int diff --git a/src/3rdparty/xkbcommon/src/scanner-utils.h b/src/3rdparty/xkbcommon/src/scanner-utils.h new file mode 100644 index 0000000000..e4e90eb0b6 --- /dev/null +++ b/src/3rdparty/xkbcommon/src/scanner-utils.h @@ -0,0 +1,159 @@ +/* + * Copyright © 2012 Ran Benita + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef XKBCOMP_SCANNER_UTILS_H +#define XKBCOMP_SCANNER_UTILS_H + +/* Point to some substring in the file; used to avoid copying. */ +struct sval { + const char *start; + unsigned int len; +}; +typedef darray(struct sval) darray_sval; + +static inline bool +svaleq(struct sval s1, struct sval s2) +{ + return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0; +} + +static inline bool +svaleq_prefix(struct sval s1, struct sval s2) +{ + return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0; +} + +struct scanner { + const char *s; + size_t pos; + size_t len; + char buf[1024]; + size_t buf_pos; + unsigned line, column; + /* The line/column of the start of the current token. */ + unsigned token_line, token_column; + const char *file_name; + struct xkb_context *ctx; +}; + +#define scanner_log(scanner, level, fmt, ...) \ + xkb_log((scanner)->ctx, (level), 0, \ + "%s:%u:%u: " fmt "\n", \ + (scanner)->file_name, \ + (scanner)->token_line, (scanner)->token_column, ##__VA_ARGS__) + +#define scanner_err(scanner, fmt, ...) \ + scanner_log(scanner, XKB_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__) + +#define scanner_warn(scanner, fmt, ...) \ + scanner_log(scanner, XKB_LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__) + +static inline void +scanner_init(struct scanner *s, struct xkb_context *ctx, + const char *string, size_t len, const char *file_name) +{ + s->s = string; + s->len = len; + s->pos = 0; + s->line = s->column = 1; + s->token_line = s->token_column = 1; + s->file_name = file_name; + s->ctx = ctx; +} + +static inline char +peek(struct scanner *s) +{ + if (unlikely(s->pos >= s->len)) + return '\0'; + return s->s[s->pos]; +} + +static inline bool +eof(struct scanner *s) +{ + return s->pos >= s->len; +} + +static inline bool +eol(struct scanner *s) +{ + return peek(s) == '\n'; +} + +static inline char +next(struct scanner *s) +{ + if (unlikely(eof(s))) + return '\0'; + if (unlikely(eol(s))) { + s->line++; + s->column = 1; + } + else { + s->column++; + } + return s->s[s->pos++]; +} + +static inline bool +chr(struct scanner *s, char ch) +{ + if (likely(peek(s) != ch)) + return false; + s->pos++; s->column++; + return true; +} + +static inline bool +str(struct scanner *s, const char *string, size_t len) +{ + if (s->len - s->pos < len) + return false; + if (strncasecmp(s->s + s->pos, string, len) != 0) + return false; + s->pos += len; s->column += len; + return true; +} + +#define lit(s, literal) str(s, literal, sizeof(literal) - 1) + +static inline bool +buf_append(struct scanner *s, char ch) +{ + if (s->buf_pos + 1 >= sizeof(s->buf)) + return false; + s->buf[s->buf_pos++] = ch; + return true; +} + +static inline bool +oct(struct scanner *s, uint8_t *out) +{ + int i; + for (i = 0, *out = 0; peek(s) >= '0' && peek(s) <= '7' && i < 3; i++) + *out = *out * 8 + next(s) - '0'; + return i > 0; +} + +#endif diff --git a/src/3rdparty/xkbcommon/src/state.c b/src/3rdparty/xkbcommon/src/state.c index 768d47c182..0f9ea79264 100644 --- a/src/3rdparty/xkbcommon/src/state.c +++ b/src/3rdparty/xkbcommon/src/state.c @@ -61,6 +61,7 @@ #include "keymap.h" #include "keysym.h" +#include "utf8.h" struct xkb_filter { union xkb_action action; @@ -108,7 +109,7 @@ struct xkb_state { * < Left Shift down, Right Shift down, Left Shift Up > * the modifier should still be set. This keeps the count. */ - int16_t mod_key_count[sizeof(xkb_mod_mask_t) * 8]; + int16_t mod_key_count[XKB_MAX_MODS]; int refcnt; darray(struct xkb_filter) filters; @@ -121,9 +122,8 @@ get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key, { const struct xkb_key_type *type = key->groups[group].type; xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask; - unsigned int i; - for (i = 0; i < type->num_entries; i++) { + for (unsigned i = 0; i < type->num_entries; i++) { /* * If the virtual modifiers are not bound to anything, we're * supposed to skip the entry (xserver does this with cached @@ -170,7 +170,7 @@ wrap_group_into_range(int32_t group, if (num_groups == 0) return XKB_LAYOUT_INVALID; - if (group < num_groups) + if (group >= 0 && (xkb_layout_index_t) group < num_groups) return group; switch (out_of_range_group_action) { @@ -623,30 +623,42 @@ xkb_state_led_update_all(struct xkb_state *state) xkb_mod_mask_t mod_mask = 0; xkb_layout_mask_t group_mask = 0; - if (led->which_mods & XKB_STATE_MODS_EFFECTIVE) - mod_mask |= state->components.mods; - if (led->which_mods & XKB_STATE_MODS_DEPRESSED) - mod_mask |= state->components.base_mods; - if (led->which_mods & XKB_STATE_MODS_LATCHED) - mod_mask |= state->components.latched_mods; - if (led->which_mods & XKB_STATE_MODS_LOCKED) - mod_mask |= state->components.locked_mods; - if (led->mods.mask & mod_mask) - state->components.leds |= (1 << idx); - - if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE) - group_mask |= (1 << state->components.group); - if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED) - group_mask |= (1 << state->components.base_group); - if (led->which_groups & XKB_STATE_LAYOUT_LATCHED) - group_mask |= (1 << state->components.latched_group); - if (led->which_groups & XKB_STATE_LAYOUT_LOCKED) - group_mask |= (1 << state->components.locked_group); - if (led->groups & group_mask) - state->components.leds |= (1 << idx); - - if (led->ctrls & state->keymap->enabled_ctrls) - state->components.leds |= (1 << idx); + if (led->which_mods != 0 && led->mods.mask != 0) { + if (led->which_mods & XKB_STATE_MODS_EFFECTIVE) + mod_mask |= state->components.mods; + if (led->which_mods & XKB_STATE_MODS_DEPRESSED) + mod_mask |= state->components.base_mods; + if (led->which_mods & XKB_STATE_MODS_LATCHED) + mod_mask |= state->components.latched_mods; + if (led->which_mods & XKB_STATE_MODS_LOCKED) + mod_mask |= state->components.locked_mods; + + if (led->mods.mask & mod_mask) { + state->components.leds |= (1u << idx); + continue; + } + } + + if (led->which_groups != 0 && led->groups != 0) { + if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE) + group_mask |= (1u << state->components.group); + if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED) + group_mask |= (1u << state->components.base_group); + if (led->which_groups & XKB_STATE_LAYOUT_LATCHED) + group_mask |= (1u << state->components.latched_group); + if (led->which_groups & XKB_STATE_LAYOUT_LOCKED) + group_mask |= (1u << state->components.locked_group); + + if (led->groups & group_mask) { + state->components.leds |= (1u << idx); + continue; + } + } + + if (led->ctrls & state->keymap->enabled_ctrls) { + state->components.leds |= (1u << idx); + continue; + } } } @@ -657,23 +669,27 @@ xkb_state_led_update_all(struct xkb_state *state) static void xkb_state_update_derived(struct xkb_state *state) { + xkb_layout_index_t wrapped; + state->components.mods = (state->components.base_mods | state->components.latched_mods | state->components.locked_mods); /* TODO: Use groups_wrap control instead of always RANGE_WRAP. */ + wrapped = wrap_group_into_range(state->components.locked_group, + state->keymap->num_groups, + RANGE_WRAP, 0); state->components.locked_group = - wrap_group_into_range(state->components.locked_group, - state->keymap->num_groups, - RANGE_WRAP, 0); + (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped); + wrapped = wrap_group_into_range(state->components.base_group + + state->components.latched_group + + state->components.locked_group, + state->keymap->num_groups, + RANGE_WRAP, 0); state->components.group = - wrap_group_into_range(state->components.base_group + - state->components.latched_group + - state->components.locked_group, - state->keymap->num_groups, - RANGE_WRAP, 0); + (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped); xkb_state_led_update_all(state); } @@ -781,7 +797,7 @@ xkb_state_update_mask(struct xkb_state *state, num_mods = xkb_keymap_num_mods(state->keymap); for (idx = 0; idx < num_mods; idx++) { - xkb_mod_mask_t mod = (1 << idx); + xkb_mod_mask_t mod = (1u << idx); if (base_mods & mod) state->components.base_mods |= mod; if (latched_mods & mod) @@ -826,6 +842,53 @@ err: return 0; } +/* + * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier + */ +static bool +should_do_caps_transformation(struct xkb_state *state, xkb_keycode_t kc) +{ + xkb_mod_index_t caps = + xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS); + + return + xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 && + xkb_state_mod_index_is_consumed(state, kc, caps) == 0; +} + +/* + * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier + */ +static bool +should_do_ctrl_transformation(struct xkb_state *state, xkb_keycode_t kc) +{ + xkb_mod_index_t ctrl = + xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CTRL); + + return + xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE) > 0 && + xkb_state_mod_index_is_consumed(state, kc, ctrl) == 0; +} + +/* Verbatim from libX11:src/xkb/XKBBind.c */ +static char +XkbToControl(char ch) +{ + char c = ch; + + if ((c >= '@' && c < '\177') || c == ' ') + c &= 0x1F; + else if (c == '2') + c = '\000'; + else if (c >= '3' && c <= '7') + c -= ('3' - '\033'); + else if (c == '8') + c = '\177'; + else if (c == '/') + c = '_' & 0x1F; + return c; +} + /** * Provides either exactly one symbol, or XKB_KEY_NoSymbol. */ @@ -835,7 +898,6 @@ xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc) const xkb_keysym_t *syms; xkb_keysym_t sym; int num_syms; - xkb_mod_index_t caps; num_syms = xkb_state_key_get_syms(state, kc, &syms); if (num_syms != 1) @@ -843,18 +905,135 @@ xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc) sym = syms[0]; - /* - * Perform capitalization transformation, see: - * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier - */ - caps = xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS); - if (xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 && - xkb_state_mod_index_is_consumed(state, kc, caps) == 0) + if (should_do_caps_transformation(state, kc)) + sym = xkb_keysym_to_upper(sym); + + return sym; +} + +/* + * The caps and ctrl transformations require some special handling, + * so we cannot simply use xkb_state_get_one_sym() for them. + * In particular, if Control is set, we must try very hard to find + * some layout in which the keysym is ASCII and thus can be (maybe) + * converted to a control character. libX11 allows to disable this + * behavior with the XkbLC_ControlFallback (see XkbSetXlibControls(3)), + * but it is enabled by default, yippee. + */ +static xkb_keysym_t +get_one_sym_for_string(struct xkb_state *state, xkb_keycode_t kc) +{ + xkb_level_index_t level; + xkb_layout_index_t layout, num_layouts; + const xkb_keysym_t *syms; + int nsyms; + xkb_keysym_t sym; + + layout = xkb_state_key_get_layout(state, kc); + num_layouts = xkb_keymap_num_layouts_for_key(state->keymap, kc); + level = xkb_state_key_get_level(state, kc, layout); + if (layout == XKB_LAYOUT_INVALID || num_layouts == 0 || + level == XKB_LEVEL_INVALID) + return XKB_KEY_NoSymbol; + + nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc, + layout, level, &syms); + if (nsyms != 1) + return XKB_KEY_NoSymbol; + sym = syms[0]; + + if (should_do_ctrl_transformation(state, kc) && sym > 127u) { + for (xkb_layout_index_t i = 0; i < num_layouts; i++) { + level = xkb_state_key_get_level(state, kc, i); + if (level == XKB_LEVEL_INVALID) + continue; + + nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc, + i, level, &syms); + if (nsyms == 1 && syms[0] <= 127u) { + sym = syms[0]; + break; + } + } + } + + if (should_do_caps_transformation(state, kc)) { sym = xkb_keysym_to_upper(sym); + } return sym; } +XKB_EXPORT int +xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t kc, + char *buffer, size_t size) +{ + xkb_keysym_t sym; + const xkb_keysym_t *syms; + int nsyms; + int offset; + char tmp[7]; + + sym = get_one_sym_for_string(state, kc); + if (sym != XKB_KEY_NoSymbol) { + nsyms = 1; syms = &sym; + } + else { + nsyms = xkb_state_key_get_syms(state, kc, &syms); + } + + /* Make sure not to truncate in the middle of a UTF-8 sequence. */ + offset = 0; + for (int i = 0; i < nsyms; i++) { + int ret = xkb_keysym_to_utf8(syms[i], tmp, sizeof(tmp)); + if (ret <= 0) + goto err_bad; + + ret--; + if ((size_t) (offset + ret) <= size) + memcpy(buffer + offset, tmp, ret); + offset += ret; + } + + if ((size_t) offset >= size) + goto err_trunc; + buffer[offset] = '\0'; + + if (!is_valid_utf8(buffer, offset)) + goto err_bad; + + if (offset == 1 && (unsigned int) buffer[0] <= 127u && + should_do_ctrl_transformation(state, kc)) + buffer[0] = XkbToControl(buffer[0]); + + return offset; + +err_trunc: + if (size > 0) + buffer[size - 1] = '\0'; + return offset; + +err_bad: + if (size > 0) + buffer[0] = '\0'; + return 0; +} + +XKB_EXPORT uint32_t +xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t kc) +{ + xkb_keysym_t sym; + uint32_t cp; + + sym = get_one_sym_for_string(state, kc); + cp = xkb_keysym_to_utf32(sym); + + if (cp <= 127u && should_do_ctrl_transformation(state, kc)) + cp = (uint32_t) XkbToControl((char) cp); + + return cp; +} + /** * Serialises the requested modifier state into an xkb_mod_mask_t, with all * the same disclaimers as in xkb_state_update_mask. @@ -913,7 +1092,7 @@ xkb_state_mod_index_is_active(struct xkb_state *state, if (idx >= xkb_keymap_num_mods(state->keymap)) return -1; - return !!(xkb_state_serialize_mods(state, type) & (1 << idx)); + return !!(xkb_state_serialize_mods(state, type) & (1u << idx)); } /** @@ -964,7 +1143,7 @@ xkb_state_mod_indices_are_active(struct xkb_state *state, ret = -1; break; } - wanted |= (1 << idx); + wanted |= (1u << idx); } va_end(ap); @@ -1015,7 +1194,7 @@ xkb_state_mod_names_are_active(struct xkb_state *state, ret = -1; break; } - wanted |= (1 << idx); + wanted |= (1u << idx); } va_end(ap); @@ -1042,11 +1221,11 @@ xkb_state_layout_index_is_active(struct xkb_state *state, if (type & XKB_STATE_LAYOUT_EFFECTIVE) ret |= (state->components.group == idx); if (type & XKB_STATE_LAYOUT_DEPRESSED) - ret |= (state->components.base_group == idx); + ret |= (state->components.base_group == (int32_t) idx); if (type & XKB_STATE_LAYOUT_LATCHED) - ret |= (state->components.latched_group == idx); + ret |= (state->components.latched_group == (int32_t) idx); if (type & XKB_STATE_LAYOUT_LOCKED) - ret |= (state->components.locked_group == idx); + ret |= (state->components.locked_group == (int32_t) idx); return ret; } @@ -1077,7 +1256,7 @@ xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx) darray_item(state->keymap->leds, idx).name == XKB_ATOM_NONE) return -1; - return !!(state->components.leds & (1 << idx)); + return !!(state->components.leds & (1u << idx)); } /** @@ -1097,18 +1276,24 @@ xkb_state_led_name_is_active(struct xkb_state *state, const char *name) static xkb_mod_mask_t key_get_consumed(struct xkb_state *state, const struct xkb_key *key) { + const struct xkb_key_type *type; const struct xkb_key_type_entry *entry; + xkb_mod_mask_t preserve; xkb_layout_index_t group; group = xkb_state_key_get_layout(state, key->keycode); if (group == XKB_LAYOUT_INVALID) return 0; + type = key->groups[group].type; + entry = get_entry_for_key_state(state, key, group); - if (!entry) - return 0; + if (entry) + preserve = entry->preserve.mask; + else + preserve = 0; - return entry->mods.mask & ~entry->preserve.mask; + return type->mods.mask & ~preserve; } /** @@ -1132,7 +1317,7 @@ xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc, if (!key || idx >= xkb_keymap_num_mods(state->keymap)) return -1; - return !!((1 << idx) & key_get_consumed(state, key)); + return !!((1u << idx) & key_get_consumed(state, key)); } /** @@ -1154,3 +1339,14 @@ xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc, return mask & ~key_get_consumed(state, key); } + +XKB_EXPORT xkb_mod_mask_t +xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t kc) +{ + const struct xkb_key *key = XkbKey(state->keymap, kc); + + if (!key) + return 0; + + return key_get_consumed(state, key); +} diff --git a/src/3rdparty/xkbcommon/src/text.c b/src/3rdparty/xkbcommon/src/text.c index 59d6c775cb..f3a09e843d 100644 --- a/src/3rdparty/xkbcommon/src/text.c +++ b/src/3rdparty/xkbcommon/src/text.c @@ -280,7 +280,7 @@ ModMaskText(const struct xkb_keymap *keymap, xkb_mod_mask_t mask) darray_enumerate(i, mod, keymap->mods) { int ret; - if (!(mask & (1 << i))) + if (!(mask & (1u << i))) continue; ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", @@ -307,14 +307,14 @@ LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask) for (unsigned i = 0; mask; i++) { int ret; - if (!(mask & (1 << i))) + if (!(mask & (1u << i))) continue; - mask &= ~(1 << i); + mask &= ~(1u << i); ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", pos == 0 ? "" : "+", - LookupValue(modComponentMaskNames, 1 << i)); + LookupValue(modComponentMaskNames, 1u << i)); if (ret <= 0 || pos + ret >= sizeof(buf)) break; else @@ -339,14 +339,14 @@ ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask) for (unsigned i = 0; mask; i++) { int ret; - if (!(mask & (1 << i))) + if (!(mask & (1u << i))) continue; - mask &= ~(1 << i); + mask &= ~(1u << i); ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", pos == 0 ? "" : "+", - LookupValue(ctrlMaskNames, 1 << i)); + LookupValue(ctrlMaskNames, 1u << i)); if (ret <= 0 || pos + ret >= sizeof(buf)) break; else diff --git a/src/3rdparty/xkbcommon/src/utf8.c b/src/3rdparty/xkbcommon/src/utf8.c new file mode 100644 index 0000000000..11382c809d --- /dev/null +++ b/src/3rdparty/xkbcommon/src/utf8.c @@ -0,0 +1,142 @@ +/* + * Copyright © 2012 Intel Corporation + * Copyright © 2014 Ran Benita + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Rob Bradford + */ + +#include +#include +#include + +#include "utf8.h" + +int +utf32_to_utf8(uint32_t unichar, char *buffer) +{ + int count, shift, length; + uint8_t head; + + if (unichar <= 0x007f) { + buffer[0] = unichar; + buffer[1] = '\0'; + return 2; + } + else if (unichar <= 0x07FF) { + length = 2; + head = 0xc0; + } + else if (unichar <= 0xffff) { + length = 3; + head = 0xe0; + } + else if (unichar <= 0x1fffff) { + length = 4; + head = 0xf0; + } + else if (unichar <= 0x3ffffff) { + length = 5; + head = 0xf8; + } + else { + length = 6; + head = 0xfc; + } + + for (count = length - 1, shift = 0; count > 0; count--, shift += 6) + buffer[count] = 0x80 | ((unichar >> shift) & 0x3f); + + buffer[0] = head | ((unichar >> shift) & 0x3f); + buffer[length] = '\0'; + + return length + 1; +} + +bool +is_valid_utf8(const char *ss, size_t len) +{ + size_t i = 0; + size_t tail_bytes = 0; + const uint8_t *s = (const uint8_t *) ss; + + /* This beauty is from: + * The Unicode Standard Version 6.2 - Core Specification, Table 3.7 + * http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G7404 + * We can optimize if needed. */ + while (i < len) + { + if (s[i] <= 0x7F) { + tail_bytes = 0; + } + else if (s[i] >= 0xC2 && s[i] <= 0xDF) { + tail_bytes = 1; + } + else if (s[i] == 0xE0) { + i++; + if (i >= len || !(s[i] >= 0xA0 && s[i] <= 0xBF)) + return false; + tail_bytes = 1; + } + else if (s[i] >= 0xE1 && s[i] <= 0xEC) { + tail_bytes = 2; + } + else if (s[i] == 0xED) { + i++; + if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x9F)) + return false; + tail_bytes = 1; + } + else if (s[i] >= 0xEE && s[i] <= 0xEF) { + tail_bytes = 2; + } + else if (s[i] == 0xF0) { + i++; + if (i >= len || !(s[i] >= 0x90 && s[i] <= 0xBF)) + return false; + tail_bytes = 2; + } + else if (s[i] >= 0xF1 && s[i] <= 0xF3) { + tail_bytes = 3; + } + else if (s[i] == 0xF4) { + i++; + if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x8F)) + return false; + tail_bytes = 2; + } + else { + return false; + } + + i++; + + while (i < len && tail_bytes > 0 && s[i] >= 0x80 && s[i] <= 0xBF) { + i++; + tail_bytes--; + } + + if (tail_bytes != 0) + return false; + } + + return true; +} diff --git a/src/3rdparty/xkbcommon/src/utf8.h b/src/3rdparty/xkbcommon/src/utf8.h new file mode 100644 index 0000000000..6371cb5596 --- /dev/null +++ b/src/3rdparty/xkbcommon/src/utf8.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2012 Intel Corporation + * Copyright © 2014 Ran Benita + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Rob Bradford + */ + +#ifndef XKBCOMMON_UTF8_H +#define XKBCOMMON_UTF8_H + +int +utf32_to_utf8(uint32_t unichar, char *buffer); + +bool +is_valid_utf8(const char *ss, size_t len); + +#endif diff --git a/src/3rdparty/xkbcommon/src/utils.h b/src/3rdparty/xkbcommon/src/utils.h index 81d1cc9412..878c2ac1e3 100644 --- a/src/3rdparty/xkbcommon/src/utils.h +++ b/src/3rdparty/xkbcommon/src/utils.h @@ -163,13 +163,13 @@ is_graph(char ch) * Note: this is 1-based! It's more useful this way, and returns 0 when * mask is all 0s. */ -static inline int +static inline unsigned msb_pos(uint32_t mask) { - int pos = 0; + unsigned pos = 0; while (mask) { pos++; - mask >>= 1; + mask >>= 1u; } return pos; } @@ -187,6 +187,22 @@ unmap_file(const char *str, size_t size); #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX3(a, b, c) MAX(MAX((a), (b)), (c)) +#if defined(HAVE_SECURE_GETENV) +# define secure_getenv secure_getenv +#elif defined(HAVE___SECURE_GETENV) +# define secure_getenv __secure_getenv +#else +# define secure_getenv getenv +#endif + +#if defined(HAVE___BUILTIN_EXPECT) +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +#else +# define likely(x) (x) +# define unlikely(x) (x) +#endif + /* Compiler Attributes */ #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__) diff --git a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c index 968f187621..76adf7428d 100644 --- a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c +++ b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c @@ -43,13 +43,13 @@ /* Constants from /usr/include/X11/extensions/XKB.h */ /* XkbNumModifiers. */ -#define NUM_REAL_MODS 8 +#define NUM_REAL_MODS 8u /* XkbNumVirtualMods. */ -#define NUM_VMODS 16 +#define NUM_VMODS 16u /* XkbNoModifier. */ #define NO_MODIFIER 0xff /* XkbNumIndicators. */ -#define NUM_INDICATORS 32 +#define NUM_INDICATORS 32u /* XkbAllIndicatorsMask. */ #define ALL_INDICATORS_MASK 0xffffffff @@ -92,11 +92,14 @@ translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high) { /* We represent mod masks in a single uint32_t value, with real mods * first and vmods after (though we don't make these distinctions). */ - return rmods | (vmods_low << 8) | (vmods_high << 16); + return + ((xkb_mod_mask_t) rmods) | + ((xkb_mod_mask_t) vmods_low << 8) | + ((xkb_mod_mask_t) vmods_high << 16); } static enum xkb_action_controls -translate_controls_mask(uint16_t wire) +translate_controls_mask(uint32_t wire) { enum xkb_action_controls ret = 0; if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS) @@ -218,8 +221,8 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire) action->ptr.x = (wire->moveptr.xLow | (wire->moveptr.xHigh << 8)); action->ptr.y = (wire->moveptr.yLow | (wire->moveptr.yHigh << 8)); - if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION) - action->ptr.flags |= ACTION_NO_ACCEL; + if (!(wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION)) + action->ptr.flags |= ACTION_ACCEL; if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_X) action->ptr.flags |= ACTION_ABSOLUTE_X; if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_Y) @@ -263,7 +266,7 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire) action->screen.screen = wire->switchscreen.newScreen; - if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION) + if (!(wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION)) action->screen.flags |= ACTION_SAME_SCREEN; if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_ABSOLUTE) action->screen.flags |= ACTION_ABSOLUTE_SWITCH; @@ -351,7 +354,7 @@ get_types(struct xkb_keymap *keymap, xcb_connection_t *conn, xcb_xkb_mod_def_iterator_t preserves_iter = xcb_xkb_key_type_preserve_iterator(wire_type); - FAIL_UNLESS(preserves_length <= type->num_entries); + FAIL_UNLESS((unsigned) preserves_length <= type->num_entries); for (int j = 0; j < preserves_length; j++) { xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data; @@ -402,7 +405,7 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn, FAIL_UNLESS(key->num_groups <= ARRAY_SIZE(wire_sym_map->kt_index)); ALLOC_OR_FAIL(key->groups, key->num_groups); - for (int j = 0; j < key->num_groups; j++) { + for (unsigned j = 0; j < key->num_groups; j++) { FAIL_UNLESS(wire_sym_map->kt_index[j] < keymap->num_types); key->groups[j].type = &keymap->types[wire_sym_map->kt_index[j]]; @@ -424,7 +427,7 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn, int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map); xcb_keysym_t *syms_iter = xcb_xkb_key_sym_map_syms(wire_sym_map); - FAIL_UNLESS(syms_length == wire_sym_map->width * key->num_groups); + FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups); for (int j = 0; j < syms_length; j++) { xcb_keysym_t wire_keysym = *syms_iter; @@ -468,9 +471,12 @@ get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn, for (int i = 0; i < acts_count_length; i++) { xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data; + int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map); uint8_t wire_count = *acts_count_iter; struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i]; + FAIL_UNLESS(wire_count == 0 || wire_count == syms_length); + for (int j = 0; j < wire_count; j++) { xcb_xkb_action_t *wire_action = acts_iter.data; const xkb_layout_index_t group = j / wire_sym_map->width; @@ -505,8 +511,8 @@ get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn, darray_resize0(keymap->mods, NUM_REAL_MODS + msb_pos(reply->virtualMods)); - for (int i = 0; i < NUM_VMODS; i++) { - if (reply->virtualMods & (1 << i)) { + for (unsigned i = 0; i < NUM_VMODS; i++) { + if (reply->virtualMods & (1u << i)) { uint8_t wire = *iter; struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i); @@ -530,11 +536,13 @@ get_explicits(struct xkb_keymap *keymap, xcb_connection_t *conn, for (int i = 0; i < length; i++) { xcb_xkb_set_explicit_t *wire = iter.data; - struct xkb_key *key = &keymap->keys[wire->keycode]; + struct xkb_key *key; FAIL_UNLESS(wire->keycode >= keymap->min_key_code && wire->keycode <= keymap->max_key_code); + key = &keymap->keys[wire->keycode]; + if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) && key->num_groups > 0) key->groups[0].explicit_type = true; @@ -573,11 +581,12 @@ get_modmaps(struct xkb_keymap *keymap, xcb_connection_t *conn, for (int i = 0; i < length; i++) { xcb_xkb_key_mod_map_t *wire = iter.data; - struct xkb_key *key = &keymap->keys[wire->keycode]; + struct xkb_key *key; FAIL_UNLESS(wire->keycode >= keymap->min_key_code && wire->keycode <= keymap->max_key_code); + key = &keymap->keys[wire->keycode]; key->modmap = wire->mods; xcb_xkb_key_mod_map_next(&iter); @@ -599,11 +608,12 @@ get_vmodmaps(struct xkb_keymap *keymap, xcb_connection_t *conn, for (int i = 0; i < length; i++) { xcb_xkb_key_v_mod_map_t *wire = iter.data; - struct xkb_key *key = &keymap->keys[wire->keycode]; + struct xkb_key *key; FAIL_UNLESS(wire->keycode >= keymap->min_key_code && wire->keycode <= keymap->max_key_code); + key = &keymap->keys[wire->keycode]; key->vmodmap = translate_mods(0, wire->vmods, 0); xcb_xkb_key_v_mod_map_next(&iter); @@ -677,8 +687,8 @@ get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn, darray_resize0(keymap->leds, msb_pos(reply->which)); - for (int i = 0; i < NUM_INDICATORS; i++) { - if (reply->which & (1 << i)) { + for (unsigned i = 0; i < NUM_INDICATORS; i++) { + if (reply->which & (1u << i)) { xcb_xkb_indicator_map_t *wire = iter.data; struct xkb_led *led = &darray_item(keymap->leds, i); @@ -879,8 +889,8 @@ get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn, FAIL_UNLESS(msb_pos(reply->indicators) <= darray_size(keymap->leds)); - for (int i = 0; i < NUM_INDICATORS; i++) { - if (reply->indicators & (1 << i)) { + for (unsigned i = 0; i < NUM_INDICATORS; i++) { + if (reply->indicators & (1u << i)) { xcb_atom_t wire = *iter; struct xkb_led *led = &darray_item(keymap->leds, i); @@ -911,8 +921,8 @@ get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn, */ darray_resize0(keymap->mods, NUM_REAL_MODS + msb_pos(reply->virtualMods)); - for (int i = 0; i < NUM_VMODS; i++) { - if (reply->virtualMods & (1 << i)) { + for (unsigned i = 0; i < NUM_VMODS; i++) { + if (reply->virtualMods & (1u << i)) { xcb_atom_t wire = *iter; struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i); @@ -959,7 +969,7 @@ get_key_names(struct xkb_keymap *keymap, xcb_connection_t *conn, FAIL_UNLESS(reply->minKeyCode == keymap->min_key_code); FAIL_UNLESS(reply->maxKeyCode == keymap->max_key_code); FAIL_UNLESS(reply->firstKey == keymap->min_key_code); - FAIL_UNLESS(reply->firstKey + reply->nKeys - 1 == keymap->max_key_code); + FAIL_UNLESS(reply->firstKey + reply->nKeys - 1U == keymap->max_key_code); for (int i = 0; i < length; i++) { xcb_xkb_key_name_t *wire = iter.data; @@ -1023,7 +1033,7 @@ static bool get_names(struct xkb_keymap *keymap, xcb_connection_t *conn, uint16_t device_id) { - static const xcb_xkb_name_detail_t required_names = + static const xcb_xkb_name_detail_t wanted = (XCB_XKB_NAME_DETAIL_KEYCODES | XCB_XKB_NAME_DETAIL_SYMBOLS | XCB_XKB_NAME_DETAIL_TYPES | @@ -1035,17 +1045,21 @@ get_names(struct xkb_keymap *keymap, xcb_connection_t *conn, XCB_XKB_NAME_DETAIL_KEY_ALIASES | XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES | XCB_XKB_NAME_DETAIL_GROUP_NAMES); + static const xcb_xkb_name_detail_t required = + (XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES | + XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES | + XCB_XKB_NAME_DETAIL_KEY_NAMES | + XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES); xcb_xkb_get_names_cookie_t cookie = - xcb_xkb_get_names(conn, device_id, required_names); + xcb_xkb_get_names(conn, device_id, wanted); xcb_xkb_get_names_reply_t *reply = xcb_xkb_get_names_reply(conn, cookie, NULL); xcb_xkb_get_names_value_list_t list; FAIL_IF_BAD_REPLY(reply, "XkbGetNames"); - if ((reply->which & required_names) != required_names) - goto fail; + FAIL_UNLESS((reply->which & required) == required); xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply), reply->nTypes, @@ -1093,13 +1107,14 @@ get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn, xcb_xkb_get_controls_reply(conn, cookie, NULL); FAIL_IF_BAD_REPLY(reply, "XkbGetControls"); + FAIL_UNLESS(reply->numGroups > 0 && reply->numGroups <= 4); keymap->enabled_ctrls = translate_controls_mask(reply->enabledControls); keymap->num_groups = reply->numGroups; FAIL_UNLESS(keymap->max_key_code < XCB_XKB_CONST_PER_KEY_BIT_ARRAY_SIZE * 8); - for (int i = keymap->min_key_code; i <= keymap->max_key_code; i++) + for (xkb_keycode_t i = keymap->min_key_code; i <= keymap->max_key_code; i++) keymap->keys[i].repeats = !!(reply->perKeyRepeat[i / 8] & (1 << (i % 8))); free(reply); @@ -1119,7 +1134,7 @@ xkb_x11_keymap_new_from_device(struct xkb_context *ctx, struct xkb_keymap *keymap; const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1; - if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { + if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { log_err_func(ctx, "unrecognized flags: %#x\n", flags); return NULL; } diff --git a/src/3rdparty/xkbcommon/src/x11/x11-priv.h b/src/3rdparty/xkbcommon/src/x11/x11-priv.h index 03f9ee6710..3a19e99c04 100644 --- a/src/3rdparty/xkbcommon/src/x11/x11-priv.h +++ b/src/3rdparty/xkbcommon/src/x11/x11-priv.h @@ -26,8 +26,8 @@ #include -#include "xkbcommon/xkbcommon-x11.h" #include "keymap.h" +#include "xkbcommon/xkbcommon-x11.h" /* Get a strdup'd name of an X atom. */ bool diff --git a/src/3rdparty/xkbcommon/src/xkb-keymap.c b/src/3rdparty/xkbcommon/src/xkb-keymap.c index 7d991d535d..892b7cf198 100644 --- a/src/3rdparty/xkbcommon/src/xkb-keymap.c +++ b/src/3rdparty/xkbcommon/src/xkb-keymap.c @@ -110,10 +110,10 @@ get_keymap_format_ops(enum xkb_keymap_format format) [XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops, }; - if ((int) format < 0 || (int) format >= ARRAY_SIZE(keymap_format_ops)) + if ((int) format < 0 || (int) format >= (int) ARRAY_SIZE(keymap_format_ops)) return NULL; - return keymap_format_ops[format]; + return keymap_format_ops[(int) format]; } XKB_EXPORT struct xkb_keymap * @@ -132,33 +132,20 @@ xkb_keymap_new_from_names(struct xkb_context *ctx, return NULL; } - if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { + if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { log_err_func(ctx, "unrecognized flags: %#x\n", flags); return NULL; } + keymap = xkb_keymap_new(ctx, format, flags); + if (!keymap) + return NULL; + if (rmlvo_in) rmlvo = *rmlvo_in; else memset(&rmlvo, 0, sizeof(rmlvo)); - - if (isempty(rmlvo.rules)) - rmlvo.rules = xkb_context_get_default_rules(ctx); - if (isempty(rmlvo.model)) - rmlvo.model = xkb_context_get_default_model(ctx); - /* Layout and variant are tied together, so don't try to use one from - * the caller and one from the environment. */ - if (isempty(rmlvo.layout)) { - rmlvo.layout = xkb_context_get_default_layout(ctx); - rmlvo.variant = xkb_context_get_default_variant(ctx); - } - /* Options can be empty, so respect that if passed in. */ - if (rmlvo.options == NULL) - rmlvo.options = xkb_context_get_default_options(ctx); - - keymap = xkb_keymap_new(ctx, format, flags); - if (!keymap) - return NULL; + xkb_context_sanitize_rule_names(ctx, &rmlvo); if (!ops->keymap_new_from_names(keymap, &rmlvo)) { xkb_keymap_unref(keymap); @@ -193,7 +180,7 @@ xkb_keymap_new_from_buffer(struct xkb_context *ctx, return NULL; } - if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { + if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { log_err_func(ctx, "unrecognized flags: %#x\n", flags); return NULL; } @@ -230,7 +217,7 @@ xkb_keymap_new_from_file(struct xkb_context *ctx, return NULL; } - if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { + if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { log_err_func(ctx, "unrecognized flags: %#x\n", flags); return NULL; } diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/action.c b/src/3rdparty/xkbcommon/src/xkbcomp/action.c index 2bd0bd1589..eb3d37fbbe 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/action.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/action.c @@ -118,6 +118,8 @@ NewActionsInfo(void) /* Increment default button. */ info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.flags = 0; info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.value = 1; + info->actions[ACTION_TYPE_PTR_MOVE].ptr.flags = ACTION_ACCEL; + info->actions[ACTION_TYPE_SWITCH_VT].screen.flags = ACTION_SAME_SCREEN; return info; } @@ -186,10 +188,10 @@ fieldText(enum action_field field) /***====================================================================***/ static inline bool -ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action, +ReportMismatch(struct xkb_context *ctx, enum xkb_action_type action, enum action_field field, const char *type) { - log_err(keymap->ctx, + log_err(ctx, "Value of %s field must be of type %s; " "Action %s definition ignored\n", fieldText(field), type, ActionTypeText(action)); @@ -197,10 +199,10 @@ ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action, } static inline bool -ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action, +ReportIllegal(struct xkb_context *ctx, enum xkb_action_type action, enum action_field field) { - log_err(keymap->ctx, + log_err(ctx, "Field %s is not defined for an action of type %s; " "Action definition ignored\n", fieldText(field), ActionTypeText(action)); @@ -208,10 +210,10 @@ ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action, } static inline bool -ReportActionNotArray(struct xkb_keymap *keymap, enum xkb_action_type action, +ReportActionNotArray(struct xkb_context *ctx, enum xkb_action_type action, enum action_field field) { - log_err(keymap->ctx, + log_err(ctx, "The %s field in the %s action is not an array; " "Action definition ignored\n", fieldText(field), ActionTypeText(action)); @@ -228,42 +230,40 @@ HandleNoAction(struct xkb_keymap *keymap, union xkb_action *action, } static bool -CheckLatchLockFlags(struct xkb_keymap *keymap, enum xkb_action_type action, - enum action_field field, const ExprDef *value, - enum xkb_action_flags *flags_inout) +CheckBooleanFlag(struct xkb_context *ctx, enum xkb_action_type action, + enum action_field field, enum xkb_action_flags flag, + const ExprDef *array_ndx, const ExprDef *value, + enum xkb_action_flags *flags_inout) { - enum xkb_action_flags tmp; - bool result; + bool set; - if (field == ACTION_FIELD_CLEAR_LOCKS) - tmp = ACTION_LOCK_CLEAR; - else if (field == ACTION_FIELD_LATCH_TO_LOCK) - tmp = ACTION_LATCH_TO_LOCK; - else - return false; /* WSGO! */ + if (array_ndx) + return ReportActionNotArray(ctx, action, field); - if (!ExprResolveBoolean(keymap->ctx, value, &result)) - return ReportMismatch(keymap, action, field, "boolean"); + if (!ExprResolveBoolean(ctx, value, &set)) + return ReportMismatch(ctx, action, field, "boolean"); - if (result) - *flags_inout |= tmp; + if (set) + *flags_inout |= flag; else - *flags_inout &= ~tmp; + *flags_inout &= ~flag; return true; } static bool CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action, - const ExprDef *value, enum xkb_action_flags *flags_inout, - xkb_mod_mask_t *mods_rtrn) + const ExprDef *array_ndx, const ExprDef *value, + enum xkb_action_flags *flags_inout, xkb_mod_mask_t *mods_rtrn) { + if (array_ndx) + return ReportActionNotArray(keymap->ctx, action, ACTION_FIELD_MODIFIERS); + if (value->expr.op == EXPR_IDENT) { const char *valStr; valStr = xkb_atom_text(keymap->ctx, value->ident.ident); if (valStr && (istreq(valStr, "usemodmapmods") || istreq(valStr, "modmapmods"))) { - *mods_rtrn = 0; *flags_inout |= ACTION_MODS_LOOKUP_MODMAP; return true; @@ -271,184 +271,130 @@ CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action, } if (!ExprResolveModMask(keymap, value, MOD_BOTH, mods_rtrn)) - return ReportMismatch(keymap, action, + return ReportMismatch(keymap->ctx, action, ACTION_FIELD_MODIFIERS, "modifier mask"); *flags_inout &= ~ACTION_MODS_LOOKUP_MODMAP; return true; } +static const LookupEntry lockWhich[] = { + { "both", 0 }, + { "lock", ACTION_LOCK_NO_UNLOCK }, + { "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) }, + { "unlock", ACTION_LOCK_NO_LOCK }, + { NULL, 0 } +}; + static bool -HandleSetLatchMods(struct xkb_keymap *keymap, union xkb_action *action, - enum action_field field, const ExprDef *array_ndx, - const ExprDef *value) +CheckAffectField(struct xkb_context *ctx, enum xkb_action_type action, + const ExprDef *array_ndx, const ExprDef *value, + enum xkb_action_flags *flags_inout) { - struct xkb_mod_action *act = &action->mods; - enum xkb_action_flags rtrn, t1; - xkb_mod_mask_t t2; - - if (array_ndx != NULL) { - switch (field) { - case ACTION_FIELD_CLEAR_LOCKS: - case ACTION_FIELD_LATCH_TO_LOCK: - case ACTION_FIELD_MODIFIERS: - return ReportActionNotArray(keymap, action->type, field); - default: - break; - } - } - - switch (field) { - case ACTION_FIELD_CLEAR_LOCKS: - case ACTION_FIELD_LATCH_TO_LOCK: - rtrn = act->flags; - if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) { - act->flags = rtrn; - return true; - } - return false; + enum xkb_action_flags flags; - case ACTION_FIELD_MODIFIERS: - t1 = act->flags; - if (CheckModifierField(keymap, action->type, value, &t1, &t2)) { - act->flags = t1; - act->mods.mods = t2; - return true; - } - return false; + if (array_ndx) + return ReportActionNotArray(ctx, action, ACTION_FIELD_AFFECT); - default: - break; - } + if (!ExprResolveEnum(ctx, value, &flags, lockWhich)) + return ReportMismatch(ctx, action, ACTION_FIELD_AFFECT, + "lock, unlock, both, neither"); - return ReportIllegal(keymap, action->type, field); + *flags_inout &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK); + *flags_inout |= flags; + return true; } static bool -HandleLockMods(struct xkb_keymap *keymap, union xkb_action *action, - enum action_field field, const ExprDef *array_ndx, - const ExprDef *value) +HandleSetLatchLockMods(struct xkb_keymap *keymap, union xkb_action *action, + enum action_field field, const ExprDef *array_ndx, + const ExprDef *value) { struct xkb_mod_action *act = &action->mods; - enum xkb_action_flags t1; - xkb_mod_mask_t t2; - - if (array_ndx && field == ACTION_FIELD_MODIFIERS) - return ReportActionNotArray(keymap, action->type, field); - - switch (field) { - case ACTION_FIELD_MODIFIERS: - t1 = act->flags; - if (CheckModifierField(keymap, action->type, value, &t1, &t2)) { - act->flags = t1; - act->mods.mods = t2; - return true; - } - return false; - - default: - break; - } - - return ReportIllegal(keymap, action->type, field); + const enum xkb_action_type type = action->type; + + if (field == ACTION_FIELD_MODIFIERS) + return CheckModifierField(keymap, action->type, array_ndx, value, + &act->flags, &act->mods.mods); + if ((type == ACTION_TYPE_MOD_SET || type == ACTION_TYPE_MOD_LATCH) && + field == ACTION_FIELD_CLEAR_LOCKS) + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_LOCK_CLEAR, array_ndx, value, + &act->flags); + if (type == ACTION_TYPE_MOD_LATCH && + field == ACTION_FIELD_LATCH_TO_LOCK) + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_LATCH_TO_LOCK, array_ndx, value, + &act->flags); + if (type == ACTION_TYPE_MOD_LOCK && + field == ACTION_FIELD_AFFECT) + return CheckAffectField(keymap->ctx, action->type, array_ndx, value, + &act->flags); + + return ReportIllegal(keymap->ctx, action->type, field); } static bool -CheckGroupField(struct xkb_keymap *keymap, unsigned action, - const ExprDef *value, enum xkb_action_flags *flags_inout, - xkb_layout_index_t *grp_rtrn) +CheckGroupField(struct xkb_context *ctx, unsigned action, + const ExprDef *array_ndx, const ExprDef *value, + enum xkb_action_flags *flags_inout, int32_t *group_rtrn) { const ExprDef *spec; + xkb_layout_index_t idx; + enum xkb_action_flags flags = *flags_inout; + + if (array_ndx) + return ReportActionNotArray(ctx, action, ACTION_FIELD_GROUP); if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { - *flags_inout &= ~ACTION_ABSOLUTE_SWITCH; + flags &= ~ACTION_ABSOLUTE_SWITCH; spec = value->unary.child; } else { - *flags_inout |= ACTION_ABSOLUTE_SWITCH; + flags |= ACTION_ABSOLUTE_SWITCH; spec = value; } - if (!ExprResolveGroup(keymap->ctx, spec, grp_rtrn)) - return ReportMismatch(keymap, action, ACTION_FIELD_GROUP, + if (!ExprResolveGroup(ctx, spec, &idx)) + return ReportMismatch(ctx, action, ACTION_FIELD_GROUP, "integer (range 1..8)"); - if (value->expr.op == EXPR_NEGATE) - *grp_rtrn = -*grp_rtrn; - else if (value->expr.op != EXPR_UNARY_PLUS) - (*grp_rtrn)--; - - return true; -} - -static bool -HandleSetLatchGroup(struct xkb_keymap *keymap, union xkb_action *action, - enum action_field field, const ExprDef *array_ndx, - const ExprDef *value) -{ - struct xkb_group_action *act = &action->group; - enum xkb_action_flags rtrn, t1; - xkb_layout_index_t t2; - - if (array_ndx != NULL) { - switch (field) { - case ACTION_FIELD_CLEAR_LOCKS: - case ACTION_FIELD_LATCH_TO_LOCK: - case ACTION_FIELD_GROUP: - return ReportActionNotArray(keymap, action->type, field); - - default: - break; - } + /* +n, -n are relative, n is absolute. */ + if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { + *group_rtrn = (int32_t) idx; + if (value->expr.op == EXPR_NEGATE) + *group_rtrn = -*group_rtrn; } - - switch (field) { - case ACTION_FIELD_CLEAR_LOCKS: - case ACTION_FIELD_LATCH_TO_LOCK: - rtrn = act->flags; - if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) { - act->flags = rtrn; - return true; - } - return false; - - case ACTION_FIELD_GROUP: - t1 = act->flags; - if (CheckGroupField(keymap, action->type, value, &t1, &t2)) { - act->flags = t1; - act->group = t2; - return true; - } - return false; - - default: - break; + else { + *group_rtrn = (int32_t) (idx - 1); } - - return ReportIllegal(keymap, action->type, field); + *flags_inout = flags; + return true; } static bool -HandleLockGroup(struct xkb_keymap *keymap, union xkb_action *action, - enum action_field field, const ExprDef *array_ndx, - const ExprDef *value) +HandleSetLatchLockGroup(struct xkb_keymap *keymap, union xkb_action *action, + enum action_field field, const ExprDef *array_ndx, + const ExprDef *value) { struct xkb_group_action *act = &action->group; - enum xkb_action_flags t1; - xkb_layout_index_t t2; - - if ((array_ndx != NULL) && (field == ACTION_FIELD_GROUP)) - return ReportActionNotArray(keymap, action->type, field); - if (field == ACTION_FIELD_GROUP) { - t1 = act->flags; - if (CheckGroupField(keymap, action->type, value, &t1, &t2)) { - act->flags = t1; - act->group = t2; - return true; - } - return false; - } - return ReportIllegal(keymap, action->type, field); + const enum xkb_action_type type = action->type; + + if (field == ACTION_FIELD_GROUP) + return CheckGroupField(keymap->ctx, action->type, array_ndx, value, + &act->flags, &act->group); + if ((type == ACTION_TYPE_GROUP_SET || type == ACTION_TYPE_GROUP_LATCH) && + field == ACTION_FIELD_CLEAR_LOCKS) + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_LOCK_CLEAR, array_ndx, value, + &act->flags); + if (type == ACTION_TYPE_GROUP_LATCH && + field == ACTION_FIELD_LATCH_TO_LOCK) + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_LATCH_TO_LOCK, array_ndx, value, + &act->flags); + + return ReportIllegal(keymap->ctx, action->type, field); } static bool @@ -458,53 +404,47 @@ HandleMovePtr(struct xkb_keymap *keymap, union xkb_action *action, { struct xkb_pointer_action *act = &action->ptr; - if (array_ndx && (field == ACTION_FIELD_X || field == ACTION_FIELD_Y)) - return ReportActionNotArray(keymap, action->type, field); - if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) { int val; const bool absolute = (value->expr.op != EXPR_NEGATE && value->expr.op != EXPR_UNARY_PLUS); + if (array_ndx) + return ReportActionNotArray(keymap->ctx, action->type, field); + if (!ExprResolveInteger(keymap->ctx, value, &val)) - return ReportMismatch(keymap, action->type, field, "integer"); + return ReportMismatch(keymap->ctx, action->type, field, "integer"); + + if (val < INT16_MIN || val > INT16_MAX) { + log_err(keymap->ctx, + "The %s field in the %s action must be in range %d..%d; " + "Action definition ignored\n", + fieldText(field), ActionTypeText(action->type), + INT16_MIN, INT16_MAX); + return false; + } if (field == ACTION_FIELD_X) { if (absolute) act->flags |= ACTION_ABSOLUTE_X; - act->x = val; + act->x = (int16_t) val; } else { if (absolute) act->flags |= ACTION_ABSOLUTE_Y; - act->y = val; + act->y = (int16_t) val; } return true; } else if (field == ACTION_FIELD_ACCEL) { - bool set; - - if (!ExprResolveBoolean(keymap->ctx, value, &set)) - return ReportMismatch(keymap, action->type, field, "boolean"); - - if (set) - act->flags &= ~ACTION_NO_ACCEL; - else - act->flags |= ACTION_NO_ACCEL; + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_ACCEL, array_ndx, value, &act->flags); } - return ReportIllegal(keymap, action->type, field); + return ReportIllegal(keymap->ctx, action->type, field); } -static const LookupEntry lockWhich[] = { - { "both", 0 }, - { "lock", ACTION_LOCK_NO_UNLOCK }, - { "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) }, - { "unlock", ACTION_LOCK_NO_LOCK }, - { NULL, 0 } -}; - static bool HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action, enum action_field field, const ExprDef *array_ndx, @@ -516,10 +456,10 @@ HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action, int btn; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (!ExprResolveButton(keymap->ctx, value, &btn)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "integer (range 1..5)"); if (btn < 0 || btn > 5) { @@ -534,40 +474,30 @@ HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action, } else if (action->type == ACTION_TYPE_PTR_LOCK && field == ACTION_FIELD_AFFECT) { - enum xkb_action_flags val; - - if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); - - if (!ExprResolveEnum(keymap->ctx, value, &val, lockWhich)) - return ReportMismatch(keymap, action->type, field, - "lock or unlock"); - - act->flags &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK); - act->flags |= val; - return true; + return CheckAffectField(keymap->ctx, action->type, array_ndx, value, + &act->flags); } else if (field == ACTION_FIELD_COUNT) { - int btn; + int val; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); - /* XXX: Should this actually be ResolveButton? */ - if (!ExprResolveButton(keymap->ctx, value, &btn)) - return ReportMismatch(keymap, action->type, field, "integer"); + if (!ExprResolveInteger(keymap->ctx, value, &val)) + return ReportMismatch(keymap->ctx, action->type, field, "integer"); - if (btn < 0 || btn > 255) { + if (val < 0 || val > 255) { log_err(keymap->ctx, "The count field must have a value in the range 0..255; " - "Illegal count %d ignored\n", btn); + "Illegal count %d ignored\n", val); return false; } - act->count = btn; + act->count = (uint8_t) val; return true; } - return ReportIllegal(keymap, action->type, field); + + return ReportIllegal(keymap->ctx, action->type, field); } static const LookupEntry ptrDflts[] = { @@ -588,10 +518,10 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action, unsigned int val; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (!ExprResolveEnum(keymap->ctx, value, &val, ptrDflts)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "pointer component"); return true; } @@ -600,7 +530,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action, int btn; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { @@ -613,7 +543,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action, } if (!ExprResolveButton(keymap->ctx, button, &btn)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "integer (range 1..5)"); if (btn < 0 || btn > 5) { @@ -633,7 +563,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action, return true; } - return ReportIllegal(keymap, action->type, field); + return ReportIllegal(keymap->ctx, action->type, field); } static bool @@ -648,7 +578,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action, int val; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { @@ -661,7 +591,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action, } if (!ExprResolveInteger(keymap->ctx, scrn, &val)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "integer (0..255)"); if (val < 0 || val > 255) { @@ -675,23 +605,12 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action, return true; } else if (field == ACTION_FIELD_SAME) { - bool set; - - if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); - - if (!ExprResolveBoolean(keymap->ctx, value, &set)) - return ReportMismatch(keymap, action->type, field, "boolean"); - - if (set) - act->flags &= ~ACTION_SAME_SCREEN; - else - act->flags |= ACTION_SAME_SCREEN; - - return true; + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_SAME_SCREEN, array_ndx, value, + &act->flags); } - return ReportIllegal(keymap, action->type, field); + return ReportIllegal(keymap->ctx, action->type, field); } static bool @@ -705,17 +624,21 @@ HandleSetLockControls(struct xkb_keymap *keymap, union xkb_action *action, unsigned int mask; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (!ExprResolveMask(keymap->ctx, value, &mask, ctrlMaskNames)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "controls mask"); act->ctrls = mask; return true; } + else if (field == ACTION_FIELD_AFFECT) { + return CheckAffectField(keymap->ctx, action->type, array_ndx, value, + &act->flags); + } - return ReportIllegal(keymap, action->type, field); + return ReportIllegal(keymap->ctx, action->type, field); } static bool @@ -728,8 +651,11 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, if (field == ACTION_FIELD_TYPE) { int type; + if (array_ndx) + return ReportActionNotArray(keymap->ctx, action->type, field); + if (!ExprResolveInteger(keymap->ctx, value, &type)) - return ReportMismatch(keymap, ACTION_TYPE_PRIVATE, field, "integer"); + return ReportMismatch(keymap->ctx, ACTION_TYPE_PRIVATE, field, "integer"); if (type < 0 || type > 255) { log_err(keymap->ctx, @@ -764,17 +690,17 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, if (array_ndx == NULL) { xkb_atom_t val; const char *str; - int len; + size_t len; if (!ExprResolveString(keymap->ctx, value, &val)) - return ReportMismatch(keymap, action->type, field, "string"); + return ReportMismatch(keymap->ctx, action->type, field, "string"); str = xkb_atom_text(keymap->ctx, val); len = strlen(str); if (len < 1 || len > 7) { log_warn(keymap->ctx, "A private action has 7 data bytes; " - "Extra %d bytes ignored\n", len - 6); + "Illegal data ignored\n"); return false; } @@ -791,7 +717,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, return false; } - if (ndx < 0 || ndx >= sizeof(act->data)) { + if (ndx < 0 || (size_t) ndx >= sizeof(act->data)) { log_err(keymap->ctx, "The data for a private action is %lu bytes long; " "Attempt to use data[%d] ignored\n", @@ -800,7 +726,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, } if (!ExprResolveInteger(keymap->ctx, value, &datum)) - return ReportMismatch(keymap, act->type, field, "integer"); + return ReportMismatch(keymap->ctx, act->type, field, "integer"); if (datum < 0 || datum > 255) { log_err(keymap->ctx, @@ -814,7 +740,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, } } - return ReportIllegal(keymap, ACTION_TYPE_NONE, field); + return ReportIllegal(keymap->ctx, ACTION_TYPE_NONE, field); } typedef bool (*actionHandler)(struct xkb_keymap *keymap, @@ -825,12 +751,12 @@ typedef bool (*actionHandler)(struct xkb_keymap *keymap, static const actionHandler handleAction[_ACTION_TYPE_NUM_ENTRIES] = { [ACTION_TYPE_NONE] = HandleNoAction, - [ACTION_TYPE_MOD_SET] = HandleSetLatchMods, - [ACTION_TYPE_MOD_LATCH] = HandleSetLatchMods, - [ACTION_TYPE_MOD_LOCK] = HandleLockMods, - [ACTION_TYPE_GROUP_SET] = HandleSetLatchGroup, - [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchGroup, - [ACTION_TYPE_GROUP_LOCK] = HandleLockGroup, + [ACTION_TYPE_MOD_SET] = HandleSetLatchLockMods, + [ACTION_TYPE_MOD_LATCH] = HandleSetLatchLockMods, + [ACTION_TYPE_MOD_LOCK] = HandleSetLatchLockMods, + [ACTION_TYPE_GROUP_SET] = HandleSetLatchLockGroup, + [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchLockGroup, + [ACTION_TYPE_GROUP_LOCK] = HandleSetLatchLockGroup, [ACTION_TYPE_PTR_MOVE] = HandleMovePtr, [ACTION_TYPE_PTR_BUTTON] = HandlePtrBtn, [ACTION_TYPE_PTR_LOCK] = HandlePtrBtn, @@ -921,7 +847,6 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap, return true; } - bool SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field, ExprDef *array_ndx, ExprDef *value, ActionsInfo *info) diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c index d470884e78..11bc0912d1 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c @@ -53,7 +53,6 @@ #include "xkbcomp-priv.h" #include "ast-build.h" -#include "parser-priv.h" #include "include.h" ParseCommon * @@ -202,7 +201,7 @@ ExprCreateKeysymList(xkb_keysym_t sym) ExprDef * ExprCreateMultiKeysymList(ExprDef *expr) { - size_t nLevels = darray_size(expr->keysym_list.symsMapIndex); + unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex); darray_resize(expr->keysym_list.symsMapIndex, 1); darray_resize(expr->keysym_list.symsNumEntries, 1); @@ -215,7 +214,7 @@ ExprCreateMultiKeysymList(ExprDef *expr) ExprDef * ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym) { - size_t nSyms = darray_size(expr->keysym_list.syms); + unsigned nSyms = darray_size(expr->keysym_list.syms); darray_append(expr->keysym_list.symsMapIndex, nSyms); darray_append(expr->keysym_list.symsNumEntries, 1); @@ -227,8 +226,8 @@ ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym) ExprDef * ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append) { - size_t nSyms = darray_size(expr->keysym_list.syms); - size_t numEntries = darray_size(append->keysym_list.syms); + unsigned nSyms = darray_size(expr->keysym_list.syms); + unsigned numEntries = darray_size(append->keysym_list.syms); darray_append(expr->keysym_list.symsMapIndex, nSyms); darray_append(expr->keysym_list.symsNumEntries, numEntries); @@ -356,7 +355,7 @@ SymbolsCreate(xkb_atom_t keyName, VarDef *symbols) } GroupCompatDef * -GroupCompatCreate(int group, ExprDef *val) +GroupCompatCreate(unsigned group, ExprDef *val) { GroupCompatDef *def = malloc(sizeof(*def)); if (!def) @@ -372,7 +371,7 @@ GroupCompatCreate(int group, ExprDef *val) } ModMapDef * -ModMapCreate(uint32_t modifier, ExprDef *keys) +ModMapCreate(xkb_atom_t modifier, ExprDef *keys) { ModMapDef *def = malloc(sizeof(*def)); if (!def) @@ -404,7 +403,7 @@ LedMapCreate(xkb_atom_t name, VarDef *body) } LedNameDef * -LedNameCreate(int ndx, ExprDef *name, bool virtual) +LedNameCreate(unsigned ndx, ExprDef *name, bool virtual) { LedNameDef *def = malloc(sizeof(*def)); if (!def) @@ -496,8 +495,8 @@ err: } XkbFile * -XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name, - ParseCommon *defs, enum xkb_map_flags flags) +XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, + enum xkb_map_flags flags) { XkbFile *file; @@ -533,7 +532,7 @@ XkbFileFromComponents(struct xkb_context *ctx, if (!include) goto err; - file = XkbFileCreate(ctx, type, NULL, &include->common, 0); + file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0); if (!file) { FreeInclude(include); goto err; @@ -542,7 +541,7 @@ XkbFileFromComponents(struct xkb_context *ctx, defs = AppendStmt(defs, &file->common); } - file = XkbFileCreate(ctx, FILE_TYPE_KEYMAP, NULL, defs, 0); + file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0); if (!file) goto err; @@ -565,7 +564,7 @@ FreeExpr(ExprDef *expr) case EXPR_UNARY_PLUS: case EXPR_NOT: case EXPR_INVERT: - FreeStmt(&expr->unary.child->common); + FreeStmt((ParseCommon *) expr->unary.child); break; case EXPR_DIVIDE: @@ -573,16 +572,16 @@ FreeExpr(ExprDef *expr) case EXPR_SUBTRACT: case EXPR_MULTIPLY: case EXPR_ASSIGN: - FreeStmt(&expr->binary.left->common); - FreeStmt(&expr->binary.right->common); + FreeStmt((ParseCommon *) expr->binary.left); + FreeStmt((ParseCommon *) expr->binary.right); break; case EXPR_ACTION_DECL: - FreeStmt(&expr->action.args->common); + FreeStmt((ParseCommon *) expr->action.args); break; case EXPR_ARRAY_REF: - FreeStmt(&expr->array_ref.entry->common); + FreeStmt((ParseCommon *) expr->array_ref.entry); break; case EXPR_KEYSYM_LIST: @@ -619,12 +618,10 @@ void FreeStmt(ParseCommon *stmt) { ParseCommon *next; - YYSTYPE u; while (stmt) { next = stmt->next; - u.any = stmt; switch (stmt->type) { case STMT_INCLUDE: @@ -633,36 +630,36 @@ FreeStmt(ParseCommon *stmt) stmt = NULL; break; case STMT_EXPR: - FreeExpr(u.expr); + FreeExpr((ExprDef *) stmt); break; case STMT_VAR: - FreeStmt(&u.var->name->common); - FreeStmt(&u.var->value->common); + FreeStmt((ParseCommon *) ((VarDef *) stmt)->name); + FreeStmt((ParseCommon *) ((VarDef *) stmt)->value); break; case STMT_TYPE: - FreeStmt(&u.keyType->body->common); + FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body); break; case STMT_INTERP: - FreeStmt(&u.interp->match->common); - FreeStmt(&u.interp->def->common); + FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match); + FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def); break; case STMT_VMOD: - FreeStmt(&u.vmod->value->common); + FreeStmt((ParseCommon *) ((VModDef *) stmt)->value); break; case STMT_SYMBOLS: - FreeStmt(&u.syms->symbols->common); + FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols); break; case STMT_MODMAP: - FreeStmt(&u.modMask->keys->common); + FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys); break; case STMT_GROUP_COMPAT: - FreeStmt(&u.groupCompat->def->common); + FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def); break; case STMT_LED_MAP: - FreeStmt(&u.ledMap->body->common); + FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body); break; case STMT_LED_NAME: - FreeStmt(&u.ledName->name->common); + FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name); break; default: break; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h index 8146b066d1..b57e4cdce1 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h @@ -98,23 +98,23 @@ SymbolsDef * SymbolsCreate(xkb_atom_t keyName, VarDef *symbols); GroupCompatDef * -GroupCompatCreate(int group, ExprDef *def); +GroupCompatCreate(unsigned group, ExprDef *def); ModMapDef * -ModMapCreate(uint32_t modifier, ExprDef *keys); +ModMapCreate(xkb_atom_t modifier, ExprDef *keys); LedMapDef * LedMapCreate(xkb_atom_t name, VarDef *body); LedNameDef * -LedNameCreate(int ndx, ExprDef *name, bool virtual); +LedNameCreate(unsigned ndx, ExprDef *name, bool virtual); IncludeStmt * IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge); XkbFile * -XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name, - ParseCommon *defs, enum xkb_map_flags flags); +XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, + enum xkb_map_flags flags); void FreeStmt(ParseCommon *stmt); diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h index 489b33193c..26cbb3a3e4 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h @@ -143,9 +143,7 @@ expr_op_type_to_string(enum expr_op_type type); const char * expr_value_type_to_string(enum expr_value_type type); -/* This struct contains fields common to all other AST nodes. It is only - * ever embedded in other structs, so save some memory by packing it. */ -typedef struct ATTR_PACKED _ParseCommon { +typedef struct _ParseCommon { struct _ParseCommon *next; enum stmt_type type; } ParseCommon; @@ -226,7 +224,7 @@ typedef struct { typedef struct { ExprCommon expr; darray(xkb_keysym_t) syms; - darray(int) symsMapIndex; + darray(unsigned int) symsMapIndex; darray(unsigned int) symsNumEntries; } ExprKeysymList; @@ -299,7 +297,7 @@ typedef struct { typedef struct { ParseCommon common; enum merge_mode merge; - int group; + unsigned group; ExprDef *def; } GroupCompatDef; @@ -314,7 +312,7 @@ typedef struct { typedef struct { ParseCommon common; enum merge_mode merge; - int ndx; + unsigned ndx; ExprDef *name; bool virtual; } LedNameDef; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c index fffb2d34b2..475895c6c1 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c @@ -54,179 +54,6 @@ #include "vmod.h" #include "include.h" -/* - * The xkb_compat section - * ===================== - * This section is the third to be processed, after xkb_keycodes and - * xkb_types. - * - * Interpret statements - * -------------------- - * Statements of the form: - * interpret Num_Lock+Any { ... } - * interpret Shift_Lock+AnyOf(Shift+Lock) { ... } - * - * The xkb_symbols section (see symbols.c) allows the keymap author to do, - * among other things, the following for each key: - * - Bind an action, like SetMods or LockGroup, to the key. Actions, like - * symbols, are specified for each level of each group in the key - * separately. - * - Add a virtual modifier to the key's virtual modifier mapping (vmodmap). - * - Specify whether the key should repeat or not. - * - * However, doing this for each key (or level) is tedious and inflexible. - * Interpret's are a mechanism to apply these settings to a bunch of - * keys/levels at once. - * - * Each interpret specifies a condition by which it attaches to certain - * levels. The condition consists of two parts: - * - A keysym. If the level has a different (or more than one) keysym, the - * match failes. Leaving out the keysym is equivalent to using the - * NoSymbol keysym, which always matches successfully. - * - A modifier predicate. The predicate consists of a matching operation - * and a mask of (real) modifiers. The modifers are matched against the - * key's modifier map (modmap). The matching operation can be one of the - * following: - * + AnyOfOrNone - The modmap must either be empty or include at least - * one of the specified modifiers. - * + AnyOf - The modmap must include at least one of the specified - * modifiers. - * + NoneOf - The modmap must not include any of the specified modifiers. - * + AllOf - The modmap must include all of the specified modifiers (but - * may include others as well). - * + Exactly - The modmap must be exactly the same as the specified - * modifiers. - * Leaving out the predicate is equivalent to usign AnyOfOrNone while - * specifying all modifiers. Leaving out just the matching condtition - * is equivalent to using Exactly. - * An interpret may also include "useModMapMods = level1;" - see below. - * - * If a level fulfils the conditions of several interpret's, only the - * most specific one is used: - * - A specific keysym will always match before a generic NoSymbol - * condition. - * - If the keysyms are the same, the interpret with the more specific - * matching operation is used. The above list is sorted from least to - * most specific. - * - If both the keysyms and the matching operations are the same (but the - * modifiers are different), the first interpret is used. - * - * As described above, once an interpret "attaches" to a level, it can bind - * an action to that level, add one virtual modifier to the key's vmodmap, - * or set the key's repeat setting. You should note the following: - * - The key repeat is a property of the entire key; it is not level-specific. - * In order to avoid confusion, it is only inspected for the first level of - * the first group; the interpret's repeat setting is ignored when applied - * to other levels. - * - If one of the above fields was set directly for a key in xkb_symbols, - * the explicit setting takes precedence over the interpret. - * - * The body of the statment may include statements of the following - * forms (all of which are optional): - * - * - useModMapMods statement: - * useModMapMods = level1; - * - * When set to 'level1', the interpret will only match levels which are - * the first level of the first group of the keys. This can be useful in - * conjunction with e.g. a virtualModifier statement. - * - * - action statement: - * action = LockMods(modifiers=NumLock); - * - * Bind this action to the matching levels. - * - * - virtual modifier statement: - * virtualModifier = NumLock; - * - * Add this virtual modifier to the key's vmodmap. The given virtual - * modifier must be declared at the top level of the file with a - * virtual_modifiers statement, e.g.: - * virtual_modifiers NumLock; - * - * - repeat statement: - * repeat = True; - * - * Set whether the key should repeat or not. Must be a boolean value. - * - * Led map statements - * ------------------------ - * Statements of the form: - * indicator "Shift Lock" { ... } - * - * This statement specifies the behavior and binding of the LED (a.k.a - * indicator) with the given name ("Shift Lock" above). The name should - * have been declared previously in the xkb_keycodes section (see Led - * name statement), and given an index there. If it wasn't, it is created - * with the next free index. - * The body of the statement describes the conditions of the keyboard - * state which will cause the LED to be lit. It may include the following - * statements: - * - * - modifiers statment: - * modifiers = ScrollLock; - * - * If the given modifiers are in the required state (see below), the - * led is lit. - * - * - whichModifierState statment: - * whichModState = Latched + Locked; - * - * Can be any combination of: - * base, latched, locked, effective - * any (i.e. all of the above) - * none (i.e. none of the above) - * compat (legacy value, treated as effective) - * This will cause the respective portion of the modifer state (see - * struct xkb_state) to be matched against the modifiers given in the - * "modifiers" statement. - * - * Here's a simple example: - * indicator "Num Lock" { - * modifiers = NumLock; - * whichModState = Locked; - * }; - * Whenever the NumLock modifier is locked, the Num Lock LED will light - * up. - * - * - groups statment: - * groups = All - group1; - * - * If the given groups are in the required state (see below), the led - * is lit. - * - * - whichGroupState statment: - * whichGroupState = Effective; - * - * Can be any combination of: - * base, latched, locked, effective - * any (i.e. all of the above) - * none (i.e. none of the above) - * This will cause the respective portion of the group state (see - * struct xkb_state) to be matched against the groups given in the - * "groups" statement. - * - * Note: the above conditions are disjunctive, i.e. if any of them are - * satisfied the led is lit. - * - * Virtual modifier statements - * --------------------------- - * Statements of the form: - * virtual_modifiers LControl; - * - * Can appear in the xkb_types, xkb_compat, xkb_symbols sections. - * TODO - * - * Effect on keymap - * ---------------- - * After all of the xkb_compat sections have been compiled, the following - * members of struct xkb_keymap are finalized: - * darray(struct xkb_sym_interpret) sym_interprets; - * darray(struct xkb_led) leds; - * char *compat_section_name; - * TODO: virtual modifiers. - */ - enum si_field { SI_FIELD_VIRTUAL_MOD = (1 << 0), SI_FIELD_ACTION = (1 << 1), @@ -555,16 +382,28 @@ MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from, from->name = NULL; } - darray_foreach(si, from->interps) { - si->merge = (merge == MERGE_DEFAULT ? si->merge : merge); - if (!AddInterp(into, si, false)) - into->errorCount++; + if (darray_empty(into->interps)) { + into->interps = from->interps; + darray_init(from->interps); + } + else { + darray_foreach(si, from->interps) { + si->merge = (merge == MERGE_DEFAULT ? si->merge : merge); + if (!AddInterp(into, si, false)) + into->errorCount++; + } } - darray_foreach(ledi, from->leds) { - ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge); - if (!AddLedMap(into, ledi, false)) - into->errorCount++; + if (darray_empty(into->leds)) { + into->leds = from->leds; + darray_init(from->leds); + } + else { + darray_foreach(ledi, from->leds) { + ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge); + if (!AddLedMap(into, ledi, false)) + into->errorCount++; + } } } @@ -929,7 +768,7 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge) ok = HandleGlobalVar(info, (VarDef *) stmt); break; case STMT_VMOD: - ok = HandleVModDef(info->keymap, (VModDef *) stmt); + ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge); break; default: log_err(info->keymap->ctx, diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c index ba71208f7e..c514f8d54c 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c @@ -116,7 +116,7 @@ LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field, if (ndx == XKB_MOD_INVALID) return false; - *val_rtrn = (1 << ndx); + *val_rtrn = (1u << ndx); return true; } @@ -427,14 +427,8 @@ ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr, bool ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn) { - int result; - - if (!ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup, - buttonNames)) - return false; - - *btn_rtrn = result; - return true; + return ExprResolveIntegerLookup(ctx, expr, btn_rtrn, SimpleLookup, + buttonNames); } bool diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c index 59916b7266..d90f6a4465 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c @@ -29,79 +29,6 @@ #include "expr.h" #include "include.h" -/* - * The xkb_keycodes section - * ======================== - * - * This is the simplest section type, and is the first one to be - * compiled. The purpose of this is mostly to map between the - * hardware/evdev scancodes and xkb keycodes. Each key is given a name - * by which it can be referred to later, e.g. in the symbols section. - * - * Keycode statements - * ------------------ - * Statements of the form: - * = 49; - * = 10; - * - * The above would let 49 and 10 be valid keycodes in the keymap, and - * assign them the names TLDE and AE01 respectively. The format is - * always used to refer to a key by name. - * - * [ The naming convention just denoted the position of the key - * in the main alphanumric section of the keyboard, with the two letters - * specifying the row and the two digits specifying the column, from - * the bottom left.] - * - * In the common case this just maps to the evdev scancodes from - * /usr/include/linux/input.h, e.g. the following definitions: - * #define KEY_GRAVE 41 - * #define KEY_1 2 - * Similar definitions appear in the xf86-input-keyboard driver. Note - * that in all current keymaps there's a constant offset of 8 (for - * historical reasons). - * - * If there's a conflict, like the same name given to different keycodes, - * or same keycode given different names, it is resolved according to the - * merge mode which applies to the definitions. - * - * Alias statements - * ---------------- - * Statements of the form: - * alias = ; - * - * Allows to refer to a previously defined key (here ) by another - * name (here ). Conflicts are handled similarly. - * - * LED name statements - * ------------------------- - * Statements of the form: - * indicator 1 = "Caps Lock"; - * indicator 2 = "Num Lock"; - * indicator 3 = "Scroll Lock"; - * - * Assigns a name to the keyboard LED (a.k.a indicator) with the given index. - * The led may be referred by this name later in the compat section - * and by the user. - * - * Effect on the keymap - * -------------------- - * After all of the xkb_keycodes sections have been compiled, the - * following members of struct xkb_keymap are finalized: - * xkb_keycode_t min_key_code; - * xkb_keycode_t max_key_code; - * unsigned int num_aliases; - * struct xkb_key_alias *key_aliases; - * char *keycodes_section_name; - * The 'name' field of leds declared in xkb_keycodes: - * darray(struct xkb_led) leds; - * Further, the array of keys: - * struct xkb_key *keys; - * had been resized to its final size (i.e. all of the xkb_key objects are - * referable by their keycode). However the objects themselves do not - * contain any useful information besides the key name at this point. - */ - typedef struct { enum merge_mode merge; @@ -322,7 +249,7 @@ AddKeyName(KeyNamesInfo *info, xkb_keycode_t kc, xkb_atom_t name, /***====================================================================***/ -static int +static bool HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge); static void @@ -459,7 +386,7 @@ HandleKeycodeDef(KeyNamesInfo *info, KeycodeDef *stmt, enum merge_mode merge) return AddKeyName(info, stmt->value, stmt->name, merge, false, true); } -static int +static bool HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge) { AliasInfo *old, new; @@ -499,7 +426,7 @@ HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge) return true; } -static int +static bool HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt) { const char *elem, *field; @@ -524,7 +451,7 @@ HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt) return true; } -static int +static bool HandleLedNameDef(KeyNamesInfo *info, LedNameDef *def, enum merge_mode merge) { diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c index 6b4c266ec0..7f70ca3481 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c @@ -92,7 +92,7 @@ check_write_buf(struct buf *buf, const char *fmt, ...) if (printed < 0) goto err; - if (printed >= available) + if ((size_t) printed >= available) if (!do_realloc(buf, printed)) goto err; @@ -103,7 +103,7 @@ check_write_buf(struct buf *buf, const char *fmt, ...) printed = vsnprintf(buf->buf + buf->size, available, fmt, args); va_end(args); - if (printed >= available || printed < 0) + if (printed < 0 || (size_t) printed >= available) goto err; buf->size += printed; @@ -273,6 +273,20 @@ write_led_map(struct xkb_keymap *keymap, struct buf *buf, return true; } +static const char * +affect_lock_text(enum xkb_action_flags flags) +{ + switch (flags & (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) { + case ACTION_LOCK_NO_UNLOCK: + return ",affect=lock"; + case ACTION_LOCK_NO_LOCK: + return ",affect=unlock"; + case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK: + return ",affect=neither"; + } + return ""; +} + static bool write_action(struct xkb_keymap *keymap, struct buf *buf, const union xkb_action *action, @@ -289,20 +303,17 @@ write_action(struct xkb_keymap *keymap, struct buf *buf, type = ActionTypeText(action->type); switch (action->type) { + case ACTION_TYPE_MOD_LOCK: case ACTION_TYPE_MOD_SET: case ACTION_TYPE_MOD_LATCH: - case ACTION_TYPE_MOD_LOCK: if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP) args = "modMapMods"; else args = ModMaskText(keymap, action->mods.mods.mods); - write_buf(buf, "%s%s(modifiers=%s%s%s)%s", prefix, type, args, - (action->type != ACTION_TYPE_MOD_LOCK && - (action->mods.flags & ACTION_LOCK_CLEAR)) ? - ",clearLocks" : "", - (action->type != ACTION_TYPE_MOD_LOCK && - (action->mods.flags & ACTION_LATCH_TO_LOCK)) ? - ",latchToLock" : "", + write_buf(buf, "%s%s(modifiers=%s%s%s%s)%s", prefix, type, args, + (action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "", + (action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "", + (action->type == ACTION_TYPE_MOD_LOCK) ? affect_lock_text(action->mods.flags) : "", suffix); break; @@ -310,16 +321,10 @@ write_action(struct xkb_keymap *keymap, struct buf *buf, case ACTION_TYPE_GROUP_LATCH: case ACTION_TYPE_GROUP_LOCK: write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type, - (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && - action->group.group > 0) ? "+" : "", - (action->group.flags & ACTION_ABSOLUTE_SWITCH) ? - action->group.group + 1 : action->group.group, - (action->type != ACTION_TYPE_GROUP_LOCK && - (action->group.flags & ACTION_LOCK_CLEAR)) ? - ",clearLocks" : "", - (action->type != ACTION_TYPE_GROUP_LOCK && - (action->group.flags & ACTION_LATCH_TO_LOCK)) ? - ",latchToLock" : "", + (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && action->group.group > 0) ? "+" : "", + (action->group.flags & ACTION_ABSOLUTE_SWITCH) ? action->group.group + 1 : action->group.group, + (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "", + (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "", suffix); break; @@ -329,35 +334,17 @@ write_action(struct xkb_keymap *keymap, struct buf *buf, case ACTION_TYPE_PTR_MOVE: write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type, - (!(action->ptr.flags & ACTION_ABSOLUTE_X) && - action->ptr.x >= 0) ? "+" : "", + (!(action->ptr.flags & ACTION_ABSOLUTE_X) && action->ptr.x >= 0) ? "+" : "", action->ptr.x, - (!(action->ptr.flags & ACTION_ABSOLUTE_Y) && - action->ptr.y >= 0) ? "+" : "", + (!(action->ptr.flags & ACTION_ABSOLUTE_Y) && action->ptr.y >= 0) ? "+" : "", action->ptr.y, - (action->ptr.flags & ACTION_NO_ACCEL) ? ",!accel" : "", + (action->ptr.flags & ACTION_ACCEL) ? "" : ",!accel", suffix); break; case ACTION_TYPE_PTR_LOCK: - switch (action->btn.flags & - (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) { - case ACTION_LOCK_NO_UNLOCK: - args = ",affect=lock"; - break; - - case ACTION_LOCK_NO_LOCK: - args = ",affect=unlock"; - break; - - case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK: - args = ",affect=neither"; - break; - - default: - args = ",affect=both"; - break; - } + args = affect_lock_text(action->btn.flags); + /* fallthrough */ case ACTION_TYPE_PTR_BUTTON: write_buf(buf, "%s%s(button=", prefix, type); if (action->btn.button > 0 && action->btn.button <= 5) @@ -374,25 +361,25 @@ write_action(struct xkb_keymap *keymap, struct buf *buf, case ACTION_TYPE_PTR_DEFAULT: write_buf(buf, "%s%s(", prefix, type); write_buf(buf, "affect=button,button=%s%d", - (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && - action->dflt.value >= 0) ? "+" : "", + (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && action->dflt.value >= 0) ? "+" : "", action->dflt.value); write_buf(buf, ")%s", suffix); break; case ACTION_TYPE_SWITCH_VT: write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type, - (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && - action->screen.screen >= 0) ? "+" : "", + (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && action->screen.screen >= 0) ? "+" : "", action->screen.screen, - (action->screen.flags & ACTION_SAME_SCREEN) ? "!" : "", + (action->screen.flags & ACTION_SAME_SCREEN) ? "" : "!", suffix); break; case ACTION_TYPE_CTRL_SET: case ACTION_TYPE_CTRL_LOCK: - write_buf(buf, "%s%s(controls=%s)%s", prefix, type, - ControlMaskText(keymap->ctx, action->ctrls.ctrls), suffix); + write_buf(buf, "%s%s(controls=%s%s)%s", prefix, type, + ControlMaskText(keymap->ctx, action->ctrls.ctrls), + (action->type == ACTION_TYPE_CTRL_LOCK) ? affect_lock_text(action->ctrls.flags) : "", + suffix); break; case ACTION_TYPE_NONE: @@ -429,7 +416,7 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf) write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n"); write_buf(buf, "\tinterpret.repeat= False;\n"); - for (int i = 0; i < keymap->num_sym_interprets; i++) { + for (unsigned i = 0; i < keymap->num_sym_interprets; i++) { const struct xkb_sym_interpret *si = &keymap->sym_interprets[i]; write_buf(buf, "\tinterpret %s+%s(%s) {\n", @@ -635,7 +622,7 @@ write_symbols(struct xkb_keymap *keymap, struct buf *buf) continue; darray_enumerate(i, mod, keymap->mods) - if (key->modmap & (1 << i)) + if (key->modmap & (1u << i)) write_buf(buf, "\tmodifier_map %s { %s };\n", xkb_atom_text(keymap->ctx, mod->name), KeyNameText(keymap->ctx, key->name)); diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c index 549cf05da6..8a70577faf 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c @@ -39,7 +39,7 @@ ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods) mods->mask = mods->mods & MOD_REAL_MASK_ALL; darray_enumerate(i, mod, keymap->mods) - if (mods->mods & (1 << i)) + if (mods->mods & (1u << i)) mods->mask |= mod->mapping; } @@ -92,7 +92,7 @@ FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key, * sym_interprets array from the most specific to the least specific, * such that when we find a match we return immediately. */ - for (int i = 0; i < keymap->num_sym_interprets; i++) { + for (unsigned i = 0; i < keymap->num_sym_interprets; i++) { const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i]; xkb_mod_mask_t mods; @@ -158,7 +158,7 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key) if ((group == 0 && level == 0) || !interp->level_one_only) if (interp->virtual_mod != XKB_MOD_INVALID) - vmodmap |= (1 << interp->virtual_mod); + vmodmap |= (1u << interp->virtual_mod); if (interp->action.type != ACTION_TYPE_NONE) key->groups[group].levels[level].action = interp->action; @@ -194,7 +194,7 @@ UpdateDerivedKeymapFields(struct xkb_keymap *keymap) /* Update keymap->mods, the virtual -> real mod mapping. */ xkb_foreach_key(key, keymap) darray_enumerate(i, mod, keymap->mods) - if (key->vmodmap & (1 << i)) + if (key->vmodmap & (1u << i)) mod->mapping |= key->modmap; /* Now update the level masks for all the types to reflect the vmods. */ diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c index c19d66ffde..abab7fe266 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c @@ -339,10 +339,9 @@ keyword_gperf_lookup (register const char *str, register unsigned int len) int -keyword_to_token(const char *string) +keyword_to_token(const char *string, unsigned int len) { - const struct keyword_tok *kt; - kt = keyword_gperf_lookup(string, strlen(string)); + const struct keyword_tok *kt = keyword_gperf_lookup(string, len); if (!kt) return -1; return kt->tok; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h index 05e725eb00..0675e55a8f 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h @@ -27,24 +27,18 @@ #ifndef XKBCOMP_PARSER_PRIV_H #define XKBCOMP_PARSER_PRIV_H -struct scanner; struct parser_param; +#include "scanner-utils.h" #include "parser.h" -int -scanner_error(struct scanner *scanner, const char *msg); - -void -scanner_warn(struct scanner *s, const char *msg); - int _xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner); XkbFile * -parse(struct xkb_context *ctx, void *scanner, const char *map); +parse(struct xkb_context *ctx, struct scanner *scanner, const char *map); int -keyword_to_token(const char *string); +keyword_to_token(const char *string, unsigned int len); #endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c index 26bbf30be8..eaa7384369 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c @@ -82,27 +82,21 @@ struct parser_param { struct xkb_context *ctx; - void *scanner; + struct scanner *scanner; XkbFile *rtrn; bool more_maps; }; -static void -parser_error(struct parser_param *param, const char *msg) -{ - scanner_error(param->scanner, msg); -} +#define parser_err(param, fmt, ...) \ + scanner_err((param)->scanner, fmt, ##__VA_ARGS__) -static void -parser_warn(struct parser_param *param, const char *msg) -{ - scanner_warn(param->scanner, msg); -} +#define parser_warn(param, fmt, ...) \ + scanner_warn((param)->scanner, fmt, ##__VA_ARGS__) static void _xkbcommon_error(struct parser_param *param, const char *msg) { - parser_error(param, msg); + parser_err(param, "%s", msg); } static bool @@ -129,11 +123,11 @@ resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn) return false; } -#define scanner param->scanner +#define param_scanner param->scanner /* Line 268 of yacc.c */ -#line 137 "src/xkbcomp/parser.c" +#line 131 "src/xkbcomp/parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -298,7 +292,7 @@ typedef union YYSTYPE { /* Line 293 of yacc.c */ -#line 167 "parser.y" +#line 161 "parser.y" int ival; int64_t num; @@ -327,7 +321,7 @@ typedef union YYSTYPE /* Line 293 of yacc.c */ -#line 331 "src/xkbcomp/parser.c" +#line 325 "src/xkbcomp/parser.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -339,7 +333,7 @@ typedef union YYSTYPE /* Line 343 of yacc.c */ -#line 343 "src/xkbcomp/parser.c" +#line 337 "src/xkbcomp/parser.c" #ifdef short # undef short @@ -698,25 +692,25 @@ static const yytype_int16 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 238, 238, 240, 242, 246, 252, 253, 254, 257, - 264, 268, 283, 284, 285, 286, 287, 290, 291, 294, - 295, 298, 299, 300, 301, 302, 303, 304, 305, 308, - 310, 313, 318, 323, 328, 333, 338, 343, 348, 353, - 358, 363, 368, 369, 370, 371, 378, 380, 382, 386, - 390, 394, 398, 400, 404, 406, 410, 416, 418, 422, - 424, 428, 434, 440, 442, 444, 447, 448, 449, 450, - 451, 454, 456, 460, 464, 468, 472, 474, 478, 480, - 484, 488, 489, 492, 494, 496, 498, 500, 504, 505, - 508, 509, 513, 514, 517, 519, 523, 527, 528, 531, - 534, 536, 540, 542, 544, 548, 550, 554, 558, 562, - 563, 564, 565, 568, 569, 572, 574, 576, 578, 580, - 582, 584, 586, 588, 590, 592, 596, 597, 600, 601, - 602, 603, 604, 614, 615, 618, 620, 624, 626, 628, - 630, 632, 634, 638, 640, 642, 644, 646, 648, 650, - 652, 656, 658, 662, 666, 668, 670, 672, 676, 678, + 0, 232, 232, 234, 236, 240, 246, 247, 248, 251, + 259, 263, 278, 279, 280, 281, 282, 285, 286, 289, + 290, 293, 294, 295, 296, 297, 298, 299, 300, 303, + 305, 308, 313, 318, 323, 328, 333, 338, 343, 348, + 353, 358, 363, 364, 365, 366, 373, 375, 377, 381, + 385, 389, 393, 396, 400, 402, 406, 412, 414, 418, + 421, 425, 431, 437, 440, 442, 445, 446, 447, 448, + 449, 452, 454, 458, 462, 466, 470, 472, 476, 478, + 482, 486, 487, 490, 492, 494, 496, 498, 502, 503, + 506, 507, 511, 512, 515, 517, 521, 525, 526, 529, + 532, 534, 538, 540, 542, 546, 548, 552, 556, 560, + 561, 562, 563, 566, 567, 570, 572, 574, 576, 578, + 580, 582, 584, 586, 588, 590, 594, 595, 598, 599, + 600, 601, 602, 612, 613, 616, 619, 623, 625, 627, + 629, 631, 633, 637, 639, 641, 643, 645, 647, 649, + 651, 655, 658, 662, 666, 668, 670, 672, 676, 678, 680, 682, 686, 687, 690, 692, 694, 696, 700, 704, - 710, 711, 725, 726, 729, 730, 733, 736, 739, 742, - 743, 746, 749, 750, 753 + 710, 711, 731, 732, 735, 736, 739, 742, 745, 748, + 749, 752, 755, 756, 759 }; #endif @@ -1217,7 +1211,7 @@ while (YYID (0)) #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else -# define YYLEX yylex (&yylval, scanner) +# define YYLEX yylex (&yylval, param_scanner) #endif /* Enable debugging if requested. */ @@ -1970,75 +1964,76 @@ yyreduce: case 2: /* Line 1806 of yacc.c */ -#line 239 "parser.y" +#line 233 "parser.y" { (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; } break; case 3: /* Line 1806 of yacc.c */ -#line 241 "parser.y" +#line 235 "parser.y" { (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; YYACCEPT; } break; case 4: /* Line 1806 of yacc.c */ -#line 243 "parser.y" +#line 237 "parser.y" { (yyval.file) = param->rtrn = NULL; param->more_maps = false; } break; case 5: /* Line 1806 of yacc.c */ -#line 249 "parser.y" - { (yyval.file) = XkbFileCreate(param->ctx, (yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), &(yyvsp[(5) - (7)].file)->common, (yyvsp[(1) - (7)].mapFlags)); } +#line 243 "parser.y" + { (yyval.file) = XkbFileCreate((yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (ParseCommon *) (yyvsp[(5) - (7)].file), (yyvsp[(1) - (7)].mapFlags)); } break; case 6: /* Line 1806 of yacc.c */ -#line 252 "parser.y" +#line 246 "parser.y" { (yyval.file_type) = FILE_TYPE_KEYMAP; } break; case 7: /* Line 1806 of yacc.c */ -#line 253 "parser.y" +#line 247 "parser.y" { (yyval.file_type) = FILE_TYPE_KEYMAP; } break; case 8: /* Line 1806 of yacc.c */ -#line 254 "parser.y" +#line 248 "parser.y" { (yyval.file_type) = FILE_TYPE_KEYMAP; } break; case 9: /* Line 1806 of yacc.c */ -#line 258 "parser.y" +#line 252 "parser.y" { if (!(yyvsp[(2) - (2)].file)) (yyval.file) = (yyvsp[(1) - (2)].file); else - (yyval.file) = (XkbFile *)AppendStmt(&(yyvsp[(1) - (2)].file)->common, &(yyvsp[(2) - (2)].file)->common); + (yyval.file) = (XkbFile *) AppendStmt((ParseCommon *) (yyvsp[(1) - (2)].file), + (ParseCommon *) (yyvsp[(2) - (2)].file)); } break; case 10: /* Line 1806 of yacc.c */ -#line 265 "parser.y" +#line 260 "parser.y" { (yyval.file) = (yyvsp[(1) - (1)].file); } break; case 11: /* Line 1806 of yacc.c */ -#line 271 "parser.y" +#line 266 "parser.y" { if ((yyvsp[(2) - (7)].file_type) == FILE_TYPE_GEOMETRY) { free((yyvsp[(3) - (7)].str)); @@ -2046,7 +2041,7 @@ yyreduce: (yyval.file) = NULL; } else { - (yyval.file) = XkbFileCreate(param->ctx, (yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (yyvsp[(5) - (7)].any), (yyvsp[(1) - (7)].mapFlags)); + (yyval.file) = XkbFileCreate((yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (yyvsp[(5) - (7)].any), (yyvsp[(1) - (7)].mapFlags)); } } break; @@ -2054,273 +2049,273 @@ yyreduce: case 12: /* Line 1806 of yacc.c */ -#line 283 "parser.y" +#line 278 "parser.y" { (yyval.file_type) = FILE_TYPE_KEYCODES; } break; case 13: /* Line 1806 of yacc.c */ -#line 284 "parser.y" +#line 279 "parser.y" { (yyval.file_type) = FILE_TYPE_TYPES; } break; case 14: /* Line 1806 of yacc.c */ -#line 285 "parser.y" +#line 280 "parser.y" { (yyval.file_type) = FILE_TYPE_COMPAT; } break; case 15: /* Line 1806 of yacc.c */ -#line 286 "parser.y" +#line 281 "parser.y" { (yyval.file_type) = FILE_TYPE_SYMBOLS; } break; case 16: /* Line 1806 of yacc.c */ -#line 287 "parser.y" +#line 282 "parser.y" { (yyval.file_type) = FILE_TYPE_GEOMETRY; } break; case 17: /* Line 1806 of yacc.c */ -#line 290 "parser.y" +#line 285 "parser.y" { (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); } break; case 18: /* Line 1806 of yacc.c */ -#line 291 "parser.y" +#line 286 "parser.y" { (yyval.mapFlags) = 0; } break; case 19: /* Line 1806 of yacc.c */ -#line 294 "parser.y" +#line 289 "parser.y" { (yyval.mapFlags) = ((yyvsp[(1) - (2)].mapFlags) | (yyvsp[(2) - (2)].mapFlags)); } break; case 20: /* Line 1806 of yacc.c */ -#line 295 "parser.y" +#line 290 "parser.y" { (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); } break; case 21: /* Line 1806 of yacc.c */ -#line 298 "parser.y" +#line 293 "parser.y" { (yyval.mapFlags) = MAP_IS_PARTIAL; } break; case 22: /* Line 1806 of yacc.c */ -#line 299 "parser.y" +#line 294 "parser.y" { (yyval.mapFlags) = MAP_IS_DEFAULT; } break; case 23: /* Line 1806 of yacc.c */ -#line 300 "parser.y" +#line 295 "parser.y" { (yyval.mapFlags) = MAP_IS_HIDDEN; } break; case 24: /* Line 1806 of yacc.c */ -#line 301 "parser.y" +#line 296 "parser.y" { (yyval.mapFlags) = MAP_HAS_ALPHANUMERIC; } break; case 25: /* Line 1806 of yacc.c */ -#line 302 "parser.y" +#line 297 "parser.y" { (yyval.mapFlags) = MAP_HAS_MODIFIER; } break; case 26: /* Line 1806 of yacc.c */ -#line 303 "parser.y" +#line 298 "parser.y" { (yyval.mapFlags) = MAP_HAS_KEYPAD; } break; case 27: /* Line 1806 of yacc.c */ -#line 304 "parser.y" +#line 299 "parser.y" { (yyval.mapFlags) = MAP_HAS_FN; } break; case 28: /* Line 1806 of yacc.c */ -#line 305 "parser.y" +#line 300 "parser.y" { (yyval.mapFlags) = MAP_IS_ALTGR; } break; case 29: /* Line 1806 of yacc.c */ -#line 309 "parser.y" +#line 304 "parser.y" { (yyval.any) = AppendStmt((yyvsp[(1) - (2)].any), (yyvsp[(2) - (2)].any)); } break; case 30: /* Line 1806 of yacc.c */ -#line 310 "parser.y" +#line 305 "parser.y" { (yyval.any) = NULL; } break; case 31: /* Line 1806 of yacc.c */ -#line 314 "parser.y" +#line 309 "parser.y" { (yyvsp[(2) - (2)].var)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].var)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].var); } break; case 32: /* Line 1806 of yacc.c */ -#line 319 "parser.y" +#line 314 "parser.y" { (yyvsp[(2) - (2)].vmod)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].vmod)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].vmod); } break; case 33: /* Line 1806 of yacc.c */ -#line 324 "parser.y" +#line 319 "parser.y" { (yyvsp[(2) - (2)].interp)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].interp)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].interp); } break; case 34: /* Line 1806 of yacc.c */ -#line 329 "parser.y" +#line 324 "parser.y" { (yyvsp[(2) - (2)].keyCode)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].keyCode)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyCode); } break; case 35: /* Line 1806 of yacc.c */ -#line 334 "parser.y" +#line 329 "parser.y" { (yyvsp[(2) - (2)].keyAlias)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].keyAlias)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyAlias); } break; case 36: /* Line 1806 of yacc.c */ -#line 339 "parser.y" +#line 334 "parser.y" { (yyvsp[(2) - (2)].keyType)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].keyType)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyType); } break; case 37: /* Line 1806 of yacc.c */ -#line 344 "parser.y" +#line 339 "parser.y" { (yyvsp[(2) - (2)].syms)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].syms)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].syms); } break; case 38: /* Line 1806 of yacc.c */ -#line 349 "parser.y" +#line 344 "parser.y" { (yyvsp[(2) - (2)].modMask)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].modMask)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].modMask); } break; case 39: /* Line 1806 of yacc.c */ -#line 354 "parser.y" +#line 349 "parser.y" { (yyvsp[(2) - (2)].groupCompat)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].groupCompat)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].groupCompat); } break; case 40: /* Line 1806 of yacc.c */ -#line 359 "parser.y" +#line 354 "parser.y" { (yyvsp[(2) - (2)].ledMap)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].ledMap)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].ledMap); } break; case 41: /* Line 1806 of yacc.c */ -#line 364 "parser.y" +#line 359 "parser.y" { (yyvsp[(2) - (2)].ledName)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].ledName)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].ledName); } break; case 42: /* Line 1806 of yacc.c */ -#line 368 "parser.y" +#line 363 "parser.y" { (yyval.any) = NULL; } break; case 43: /* Line 1806 of yacc.c */ -#line 369 "parser.y" +#line 364 "parser.y" { (yyval.any) = NULL; } break; case 44: /* Line 1806 of yacc.c */ -#line 370 "parser.y" +#line 365 "parser.y" { (yyval.any) = NULL; } break; case 45: /* Line 1806 of yacc.c */ -#line 372 "parser.y" +#line 367 "parser.y" { - (yyval.any) = &IncludeCreate(param->ctx, (yyvsp[(2) - (2)].str), (yyvsp[(1) - (2)].merge))->common; + (yyval.any) = (ParseCommon *) IncludeCreate(param->ctx, (yyvsp[(2) - (2)].str), (yyvsp[(1) - (2)].merge)); free((yyvsp[(2) - (2)].str)); } break; @@ -2328,609 +2323,612 @@ yyreduce: case 46: /* Line 1806 of yacc.c */ -#line 379 "parser.y" +#line 374 "parser.y" { (yyval.var) = VarCreate((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr)); } break; case 47: /* Line 1806 of yacc.c */ -#line 381 "parser.y" +#line 376 "parser.y" { (yyval.var) = BoolVarCreate((yyvsp[(1) - (2)].sval), true); } break; case 48: /* Line 1806 of yacc.c */ -#line 383 "parser.y" +#line 378 "parser.y" { (yyval.var) = BoolVarCreate((yyvsp[(2) - (3)].sval), false); } break; case 49: /* Line 1806 of yacc.c */ -#line 387 "parser.y" +#line 382 "parser.y" { (yyval.keyCode) = KeycodeCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].num)); } break; case 50: /* Line 1806 of yacc.c */ -#line 391 "parser.y" +#line 386 "parser.y" { (yyval.keyAlias) = KeyAliasCreate((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].sval)); } break; case 51: /* Line 1806 of yacc.c */ -#line 395 "parser.y" +#line 390 "parser.y" { (yyval.vmod) = (yyvsp[(2) - (3)].vmod); } break; case 52: /* Line 1806 of yacc.c */ -#line 399 "parser.y" - { (yyval.vmod) = (VModDef *)AppendStmt(&(yyvsp[(1) - (3)].vmod)->common, &(yyvsp[(3) - (3)].vmod)->common); } +#line 394 "parser.y" + { (yyval.vmod) = (VModDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].vmod), + (ParseCommon *) (yyvsp[(3) - (3)].vmod)); } break; case 53: /* Line 1806 of yacc.c */ -#line 401 "parser.y" +#line 397 "parser.y" { (yyval.vmod) = (yyvsp[(1) - (1)].vmod); } break; case 54: /* Line 1806 of yacc.c */ -#line 405 "parser.y" +#line 401 "parser.y" { (yyval.vmod) = VModCreate((yyvsp[(1) - (1)].sval), NULL); } break; case 55: /* Line 1806 of yacc.c */ -#line 407 "parser.y" +#line 403 "parser.y" { (yyval.vmod) = VModCreate((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr)); } break; case 56: /* Line 1806 of yacc.c */ -#line 413 "parser.y" +#line 409 "parser.y" { (yyvsp[(2) - (6)].interp)->def = (yyvsp[(4) - (6)].var); (yyval.interp) = (yyvsp[(2) - (6)].interp); } break; case 57: /* Line 1806 of yacc.c */ -#line 417 "parser.y" +#line 413 "parser.y" { (yyval.interp) = InterpCreate((yyvsp[(1) - (3)].keysym), (yyvsp[(3) - (3)].expr)); } break; case 58: /* Line 1806 of yacc.c */ -#line 419 "parser.y" +#line 415 "parser.y" { (yyval.interp) = InterpCreate((yyvsp[(1) - (1)].keysym), NULL); } break; case 59: /* Line 1806 of yacc.c */ -#line 423 "parser.y" - { (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (2)].var)->common, &(yyvsp[(2) - (2)].var)->common); } +#line 419 "parser.y" + { (yyval.var) = (VarDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (2)].var), + (ParseCommon *) (yyvsp[(2) - (2)].var)); } break; case 60: /* Line 1806 of yacc.c */ -#line 425 "parser.y" +#line 422 "parser.y" { (yyval.var) = (yyvsp[(1) - (1)].var); } break; case 61: /* Line 1806 of yacc.c */ -#line 431 "parser.y" +#line 428 "parser.y" { (yyval.keyType) = KeyTypeCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); } break; case 62: /* Line 1806 of yacc.c */ -#line 437 "parser.y" +#line 434 "parser.y" { (yyval.syms) = SymbolsCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); } break; case 63: /* Line 1806 of yacc.c */ -#line 441 "parser.y" - { (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (3)].var)->common, &(yyvsp[(3) - (3)].var)->common); } +#line 438 "parser.y" + { (yyval.var) = (VarDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].var), + (ParseCommon *) (yyvsp[(3) - (3)].var)); } break; case 64: /* Line 1806 of yacc.c */ -#line 443 "parser.y" +#line 441 "parser.y" { (yyval.var) = (yyvsp[(1) - (1)].var); } break; case 65: /* Line 1806 of yacc.c */ -#line 444 "parser.y" +#line 442 "parser.y" { (yyval.var) = NULL; } break; case 66: /* Line 1806 of yacc.c */ -#line 447 "parser.y" +#line 445 "parser.y" { (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 67: /* Line 1806 of yacc.c */ -#line 448 "parser.y" +#line 446 "parser.y" { (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 68: /* Line 1806 of yacc.c */ -#line 449 "parser.y" +#line 447 "parser.y" { (yyval.var) = BoolVarCreate((yyvsp[(1) - (1)].sval), true); } break; case 69: /* Line 1806 of yacc.c */ -#line 450 "parser.y" +#line 448 "parser.y" { (yyval.var) = BoolVarCreate((yyvsp[(2) - (2)].sval), false); } break; case 70: /* Line 1806 of yacc.c */ -#line 451 "parser.y" +#line 449 "parser.y" { (yyval.var) = VarCreate(NULL, (yyvsp[(1) - (1)].expr)); } break; case 71: /* Line 1806 of yacc.c */ -#line 455 "parser.y" +#line 453 "parser.y" { (yyval.expr) = (yyvsp[(2) - (3)].expr); } break; case 72: /* Line 1806 of yacc.c */ -#line 457 "parser.y" +#line 455 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, (yyvsp[(2) - (3)].expr)); } break; case 73: /* Line 1806 of yacc.c */ -#line 461 "parser.y" +#line 459 "parser.y" { (yyval.groupCompat) = GroupCompatCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr)); } break; case 74: /* Line 1806 of yacc.c */ -#line 465 "parser.y" +#line 463 "parser.y" { (yyval.modMask) = ModMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].expr)); } break; case 75: /* Line 1806 of yacc.c */ -#line 469 "parser.y" +#line 467 "parser.y" { (yyval.ledMap) = LedMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); } break; case 76: /* Line 1806 of yacc.c */ -#line 473 "parser.y" +#line 471 "parser.y" { (yyval.ledName) = LedNameCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr), false); } break; case 77: /* Line 1806 of yacc.c */ -#line 475 "parser.y" +#line 473 "parser.y" { (yyval.ledName) = LedNameCreate((yyvsp[(3) - (6)].ival), (yyvsp[(5) - (6)].expr), true); } break; case 78: /* Line 1806 of yacc.c */ -#line 479 "parser.y" +#line 477 "parser.y" { (yyval.geom) = NULL; } break; case 79: /* Line 1806 of yacc.c */ -#line 481 "parser.y" +#line 479 "parser.y" { (yyval.geom) = NULL; } break; case 80: /* Line 1806 of yacc.c */ -#line 485 "parser.y" +#line 483 "parser.y" { (yyval.geom) = NULL; } break; case 81: /* Line 1806 of yacc.c */ -#line 488 "parser.y" +#line 486 "parser.y" { (yyval.geom) = NULL;} break; case 82: /* Line 1806 of yacc.c */ -#line 489 "parser.y" +#line 487 "parser.y" { (yyval.geom) = NULL; } break; case 83: /* Line 1806 of yacc.c */ -#line 493 "parser.y" +#line 491 "parser.y" { (yyval.geom) = NULL; } break; case 84: /* Line 1806 of yacc.c */ -#line 495 "parser.y" - { FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; } +#line 493 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].var)); (yyval.geom) = NULL; } break; case 85: /* Line 1806 of yacc.c */ -#line 497 "parser.y" +#line 495 "parser.y" { (yyval.geom) = NULL; } break; case 86: /* Line 1806 of yacc.c */ -#line 499 "parser.y" - { FreeStmt(&(yyvsp[(1) - (1)].ledMap)->common); (yyval.geom) = NULL; } +#line 497 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].ledMap)); (yyval.geom) = NULL; } break; case 87: /* Line 1806 of yacc.c */ -#line 501 "parser.y" +#line 499 "parser.y" { (yyval.geom) = NULL; } break; case 88: /* Line 1806 of yacc.c */ -#line 504 "parser.y" +#line 502 "parser.y" { (yyval.geom) = NULL;} break; case 89: /* Line 1806 of yacc.c */ -#line 505 "parser.y" +#line 503 "parser.y" { (yyval.geom) = NULL; } break; case 90: /* Line 1806 of yacc.c */ -#line 508 "parser.y" +#line 506 "parser.y" { (yyval.geom) = NULL; } break; case 91: /* Line 1806 of yacc.c */ -#line 510 "parser.y" - { FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; } +#line 508 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].var)); (yyval.geom) = NULL; } break; case 92: /* Line 1806 of yacc.c */ -#line 513 "parser.y" +#line 511 "parser.y" { (yyval.geom) = NULL; } break; case 93: /* Line 1806 of yacc.c */ -#line 514 "parser.y" +#line 512 "parser.y" { (yyval.geom) = NULL; } break; case 94: /* Line 1806 of yacc.c */ -#line 518 "parser.y" +#line 516 "parser.y" { (yyval.geom) = NULL; } break; case 95: /* Line 1806 of yacc.c */ -#line 520 "parser.y" - { FreeStmt(&(yyvsp[(2) - (3)].expr)->common); (yyval.geom) = NULL; } +#line 518 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(2) - (3)].expr)); (yyval.geom) = NULL; } break; case 96: /* Line 1806 of yacc.c */ -#line 524 "parser.y" +#line 522 "parser.y" { (yyval.geom) = NULL; } break; case 97: /* Line 1806 of yacc.c */ -#line 527 "parser.y" +#line 525 "parser.y" { (yyval.geom) = NULL; } break; case 98: /* Line 1806 of yacc.c */ -#line 528 "parser.y" +#line 526 "parser.y" { (yyval.geom) = NULL; } break; case 99: /* Line 1806 of yacc.c */ -#line 531 "parser.y" +#line 529 "parser.y" { (yyval.geom) = NULL; } break; case 100: /* Line 1806 of yacc.c */ -#line 535 "parser.y" +#line 533 "parser.y" { (yyval.geom) = NULL;} break; case 101: /* Line 1806 of yacc.c */ -#line 537 "parser.y" +#line 535 "parser.y" { (yyval.geom) = NULL; } break; case 102: /* Line 1806 of yacc.c */ -#line 541 "parser.y" +#line 539 "parser.y" { (yyval.geom) = NULL; } break; case 103: /* Line 1806 of yacc.c */ -#line 543 "parser.y" +#line 541 "parser.y" { (yyval.geom) = NULL; } break; case 104: /* Line 1806 of yacc.c */ -#line 545 "parser.y" - { FreeStmt(&(yyvsp[(3) - (3)].expr)->common); (yyval.geom) = NULL; } +#line 543 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(3) - (3)].expr)); (yyval.geom) = NULL; } break; case 105: /* Line 1806 of yacc.c */ -#line 549 "parser.y" +#line 547 "parser.y" { (yyval.expr) = NULL; } break; case 106: /* Line 1806 of yacc.c */ -#line 551 "parser.y" +#line 549 "parser.y" { (yyval.expr) = NULL; } break; case 107: /* Line 1806 of yacc.c */ -#line 555 "parser.y" +#line 553 "parser.y" { (yyval.expr) = NULL; } break; case 108: /* Line 1806 of yacc.c */ -#line 559 "parser.y" - { FreeStmt(&(yyvsp[(4) - (6)].var)->common); (yyval.geom) = NULL; } +#line 557 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(4) - (6)].var)); (yyval.geom) = NULL; } break; case 109: /* Line 1806 of yacc.c */ -#line 562 "parser.y" +#line 560 "parser.y" { (yyval.ival) = 0; } break; case 110: /* Line 1806 of yacc.c */ -#line 563 "parser.y" +#line 561 "parser.y" { (yyval.ival) = 0; } break; case 111: /* Line 1806 of yacc.c */ -#line 564 "parser.y" +#line 562 "parser.y" { (yyval.ival) = 0; } break; case 112: /* Line 1806 of yacc.c */ -#line 565 "parser.y" +#line 563 "parser.y" { (yyval.ival) = 0; } break; case 113: /* Line 1806 of yacc.c */ -#line 568 "parser.y" +#line 566 "parser.y" { (yyval.sval) = (yyvsp[(1) - (1)].sval); } break; case 114: /* Line 1806 of yacc.c */ -#line 569 "parser.y" +#line 567 "parser.y" { (yyval.sval) = (yyvsp[(1) - (1)].sval); } break; case 115: /* Line 1806 of yacc.c */ -#line 573 "parser.y" +#line 571 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "action"); } break; case 116: /* Line 1806 of yacc.c */ -#line 575 "parser.y" +#line 573 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "interpret"); } break; case 117: /* Line 1806 of yacc.c */ -#line 577 "parser.y" +#line 575 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "type"); } break; case 118: /* Line 1806 of yacc.c */ -#line 579 "parser.y" +#line 577 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "key"); } break; case 119: /* Line 1806 of yacc.c */ -#line 581 "parser.y" +#line 579 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "group"); } break; case 120: /* Line 1806 of yacc.c */ -#line 583 "parser.y" +#line 581 "parser.y" {(yyval.sval) = xkb_atom_intern_literal(param->ctx, "modifier_map");} break; case 121: /* Line 1806 of yacc.c */ -#line 585 "parser.y" +#line 583 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "indicator"); } break; case 122: /* Line 1806 of yacc.c */ -#line 587 "parser.y" +#line 585 "parser.y" { (yyval.sval) = XKB_ATOM_NONE; } break; case 123: /* Line 1806 of yacc.c */ -#line 589 "parser.y" +#line 587 "parser.y" { (yyval.sval) = XKB_ATOM_NONE; } break; case 124: /* Line 1806 of yacc.c */ -#line 591 "parser.y" +#line 589 "parser.y" { (yyval.sval) = XKB_ATOM_NONE; } break; case 125: /* Line 1806 of yacc.c */ -#line 593 "parser.y" +#line 591 "parser.y" { (yyval.sval) = XKB_ATOM_NONE; } break; case 126: /* Line 1806 of yacc.c */ -#line 596 "parser.y" +#line 594 "parser.y" { (yyval.merge) = (yyvsp[(1) - (1)].merge); } break; case 127: /* Line 1806 of yacc.c */ -#line 597 "parser.y" +#line 595 "parser.y" { (yyval.merge) = MERGE_DEFAULT; } break; case 128: /* Line 1806 of yacc.c */ -#line 600 "parser.y" +#line 598 "parser.y" { (yyval.merge) = MERGE_DEFAULT; } break; case 129: /* Line 1806 of yacc.c */ -#line 601 "parser.y" +#line 599 "parser.y" { (yyval.merge) = MERGE_AUGMENT; } break; case 130: /* Line 1806 of yacc.c */ -#line 602 "parser.y" +#line 600 "parser.y" { (yyval.merge) = MERGE_OVERRIDE; } break; case 131: /* Line 1806 of yacc.c */ -#line 603 "parser.y" +#line 601 "parser.y" { (yyval.merge) = MERGE_REPLACE; } break; case 132: /* Line 1806 of yacc.c */ -#line 605 "parser.y" +#line 603 "parser.y" { /* * This used to be MERGE_ALT_FORM. This functionality was @@ -2943,134 +2941,136 @@ yyreduce: case 133: /* Line 1806 of yacc.c */ -#line 614 "parser.y" +#line 612 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 134: /* Line 1806 of yacc.c */ -#line 615 "parser.y" +#line 613 "parser.y" { (yyval.expr) = NULL; } break; case 135: /* Line 1806 of yacc.c */ -#line 619 "parser.y" - { (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); } +#line 617 "parser.y" + { (yyval.expr) = (ExprDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].expr), + (ParseCommon *) (yyvsp[(3) - (3)].expr)); } break; case 136: /* Line 1806 of yacc.c */ -#line 621 "parser.y" +#line 620 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 137: /* Line 1806 of yacc.c */ -#line 625 "parser.y" +#line 624 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_DIVIDE, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 138: /* Line 1806 of yacc.c */ -#line 627 "parser.y" +#line 626 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_ADD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 139: /* Line 1806 of yacc.c */ -#line 629 "parser.y" +#line 628 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_SUBTRACT, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 140: /* Line 1806 of yacc.c */ -#line 631 "parser.y" +#line 630 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_MULTIPLY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 141: /* Line 1806 of yacc.c */ -#line 633 "parser.y" +#line 632 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_ASSIGN, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 142: /* Line 1806 of yacc.c */ -#line 635 "parser.y" +#line 634 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 143: /* Line 1806 of yacc.c */ -#line 639 "parser.y" +#line 638 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_NEGATE, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); } break; case 144: /* Line 1806 of yacc.c */ -#line 641 "parser.y" +#line 640 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_UNARY_PLUS, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); } break; case 145: /* Line 1806 of yacc.c */ -#line 643 "parser.y" +#line 642 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, (yyvsp[(2) - (2)].expr)); } break; case 146: /* Line 1806 of yacc.c */ -#line 645 "parser.y" +#line 644 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_INVERT, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); } break; case 147: /* Line 1806 of yacc.c */ -#line 647 "parser.y" +#line 646 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 148: /* Line 1806 of yacc.c */ -#line 649 "parser.y" +#line 648 "parser.y" { (yyval.expr) = ExprCreateAction((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); } break; case 149: /* Line 1806 of yacc.c */ -#line 651 "parser.y" +#line 650 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 150: /* Line 1806 of yacc.c */ -#line 653 "parser.y" +#line 652 "parser.y" { (yyval.expr) = (yyvsp[(2) - (3)].expr); } break; case 151: /* Line 1806 of yacc.c */ -#line 657 "parser.y" - { (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); } +#line 656 "parser.y" + { (yyval.expr) = (ExprDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].expr), + (ParseCommon *) (yyvsp[(3) - (3)].expr)); } break; case 152: @@ -3215,14 +3215,20 @@ yyreduce: /* Line 1806 of yacc.c */ #line 712 "parser.y" { - if ((yyvsp[(1) - (1)].ival) < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */ - (yyval.keysym) = XKB_KEY_0 + (yyvsp[(1) - (1)].ival); + if ((yyvsp[(1) - (1)].ival) < 0) { + parser_warn(param, "unrecognized keysym"); + (yyval.keysym) = XKB_KEY_NoSymbol; + } + else if ((yyvsp[(1) - (1)].ival) < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */ + (yyval.keysym) = XKB_KEY_0 + (xkb_keysym_t) (yyvsp[(1) - (1)].ival); } else { char buf[17]; snprintf(buf, sizeof(buf), "0x%x", (yyvsp[(1) - (1)].ival)); - if (!resolve_keysym(buf, &(yyval.keysym))) + if (!resolve_keysym(buf, &(yyval.keysym))) { parser_warn(param, "unrecognized keysym"); + (yyval.keysym) = XKB_KEY_NoSymbol; + } } } break; @@ -3230,98 +3236,98 @@ yyreduce: case 172: /* Line 1806 of yacc.c */ -#line 725 "parser.y" +#line 731 "parser.y" { (yyval.ival) = -(yyvsp[(2) - (2)].ival); } break; case 173: /* Line 1806 of yacc.c */ -#line 726 "parser.y" +#line 732 "parser.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); } break; case 174: /* Line 1806 of yacc.c */ -#line 729 "parser.y" +#line 735 "parser.y" { (yyval.ival) = (yyvsp[(1) - (1)].num); } break; case 175: /* Line 1806 of yacc.c */ -#line 730 "parser.y" +#line 736 "parser.y" { (yyval.ival) = (yyvsp[(1) - (1)].num); } break; case 176: /* Line 1806 of yacc.c */ -#line 733 "parser.y" +#line 739 "parser.y" { (yyval.ival) = 0; } break; case 177: /* Line 1806 of yacc.c */ -#line 736 "parser.y" +#line 742 "parser.y" { (yyval.ival) = (yyvsp[(1) - (1)].num); } break; case 178: /* Line 1806 of yacc.c */ -#line 739 "parser.y" +#line 745 "parser.y" { (yyval.num) = (yyvsp[(1) - (1)].num); } break; case 179: /* Line 1806 of yacc.c */ -#line 742 "parser.y" +#line 748 "parser.y" { (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); } break; case 180: /* Line 1806 of yacc.c */ -#line 743 "parser.y" +#line 749 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "default"); } break; case 181: /* Line 1806 of yacc.c */ -#line 746 "parser.y" +#line 752 "parser.y" { (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); } break; case 182: /* Line 1806 of yacc.c */ -#line 749 "parser.y" +#line 755 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 183: /* Line 1806 of yacc.c */ -#line 750 "parser.y" +#line 756 "parser.y" { (yyval.str) = NULL; } break; case 184: /* Line 1806 of yacc.c */ -#line 753 "parser.y" +#line 759 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; /* Line 1806 of yacc.c */ -#line 3325 "src/xkbcomp/parser.c" +#line 3331 "src/xkbcomp/parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -3552,13 +3558,11 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 756 "parser.y" +#line 762 "parser.y" -#undef scanner - XkbFile * -parse(struct xkb_context *ctx, void *scanner, const char *map) +parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) { int ret; XkbFile *first = NULL; @@ -3604,5 +3608,3 @@ parse(struct xkb_context *ctx, void *scanner, const char *map) return first; } -#define scanner param->scanner - diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h index f85a2bad85..ee9b4468b5 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h @@ -175,7 +175,7 @@ typedef union YYSTYPE { /* Line 2068 of yacc.c */ -#line 167 "parser.y" +#line 161 "parser.y" int ival; int64_t num; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c index de82d96119..61799e7059 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c @@ -52,84 +52,6 @@ #include "include.h" #include "scanner-utils.h" -/* - * The rules file - * ============== - * The purpose of this file is to map between configuration values that - * are easy for a user to specify and understand, and the configuration - * values xkbcomp uses and understands. - * xkbcomp uses the xkb_component_names struct, which maps directly to - * include statements of the appropriate sections, called for short - * KcCGST (see keycodes.c, types.c, compat.c, symbols.c; geometry.c was - * removed). These are not really intuitive or straight-forward for - * the uninitiated. - * Instead, the user passes in a xkb_rule_names struct, which consists - * of the name of a rules file (in Linux this is usually "evdev"), a - * keyboard model (e.g. "pc105"), a set of layouts (which will end up - * in different groups, e.g. "us,fr"), variants (used to alter/augment - * the respective layout, e.g. "intl,dvorak"), and a set of options - * (used to tweak some general behavior of the keyboard, e.g. - * "ctrl:nocaps,compose:menu" to make the Caps Lock key act like Ctrl - * and the Menu key like Compose). We call these RMLVO. - * - * Format of the file - * ------------------ - * The file consists of rule sets, each consisting of rules (one per - * line), which match the MLVO values on the left hand side, and, if - * the values match to the values the user passed in, results in the - * values on the right hand side being added to the resulting KcCGST. - * Since some values are related and repeated often, it is possible - * to group them together and refer to them by a group name in the - * rules. - * Along with matching values by simple string equality, and for - * membership in a group defined previously, rules may also contain - * "wildcard" values - "*" - which always match. These usually appear - * near the end. - * - * Grammer - * ------- - * (It might be helpful to look at a file like rules/evdev along with - * this grammer. Comments, whitespace, etc. are not shown.) - * - * File ::= { "!" (Group | RuleSet) } - * - * Group ::= GroupName "=" { GroupElement } "\n" - * GroupName ::= "$" - * GroupElement ::= - * - * RuleSet ::= Mapping { Rule } - * - * Mapping ::= { Mlvo } "=" { Kccgst } "\n" - * Mlvo ::= "model" | "option" | ("layout" | "variant") [ Index ] - * Index ::= "[" 1..XKB_NUM_GROUPS "]" - * Kccgst ::= "keycodes" | "symbols" | "types" | "compat" | "geometry" - * - * Rule ::= { MlvoValue } "=" { KccgstValue } "\n" - * MlvoValue ::= "*" | GroupName | - * KccgstValue ::= - * - * Notes: - * - The order of values in a Rule must be the same as the Mapping it - * follows. The mapping line determines the meaning of the values in - * the rules which follow in the RuleSet. - * - If a Rule is matched, %-expansion is performed on the KccgstValue, - * as follows: - * %m, %l, %v: - * The model, layout or variant, if only one was given (e.g. - * %l for "us,il" is invalid). - * %l[1], %v[1]: - * Layout or variant for the specified group Index, if more than - * one was given (e.g. %l[1] for "us" is invalid). - * %+m, %+l, %+v, %+l[1], %+v[1] - * As above, but prefixed with '+'. Similarly, '|', '-', '_' may be - * used instead of '+'. - * %(m), %(l), %(l[1]), %(v), %(v[1]): - * As above, but prefixed by '(' and suffixed by ')'. - * In case the expansion is invalid, as described above, it is - * skipped (the rest of the string is still processed); this includes - * the prefix and suffix (that's why you shouldn't use e.g. "(%v[1])"). - */ - /* Scanner / Lexer */ /* Values returned with some tokens, like yylval. */ @@ -137,14 +59,6 @@ union lvalue { struct sval string; }; -/* - * Holds the location in the file of the last processed token, - * like yylloc. - */ -struct location { - int line, column; -}; - enum rules_token { TOK_END_OF_FILE = 0, TOK_END_OF_LINE, @@ -156,14 +70,6 @@ enum rules_token { TOK_ERROR }; -/* C99 is stupid. Just use the 1 variant when there are no args. */ -#define scanner_error1(scanner, loc, msg) \ - log_warn((scanner)->ctx, "rules/%s:%d:%d: %s\n", \ - (scanner)->file_name, (loc)->line, (loc)->column, msg) -#define scanner_error(scanner, loc, fmt, ...) \ - log_warn((scanner)->ctx, "rules/%s:%d:%d: " fmt "\n", \ - (scanner)->file_name, (loc)->line, (loc)->column, __VA_ARGS__) - static inline bool is_ident(char ch) { @@ -171,7 +77,7 @@ is_ident(char ch) } static enum rules_token -lex(struct scanner *s, union lvalue *val, struct location *loc) +lex(struct scanner *s, union lvalue *val) { skip_more_whitespace_and_comments: /* Skip spaces. */ @@ -191,8 +97,7 @@ skip_more_whitespace_and_comments: /* Escaped line continuation. */ if (chr(s, '\\')) { if (!eol(s)) { - scanner_error1(s, loc, - "illegal new line escape; must appear at end of line"); + scanner_err(s, "illegal new line escape; must appear at end of line"); return TOK_ERROR; } next(s); @@ -203,8 +108,8 @@ skip_more_whitespace_and_comments: if (eof(s)) return TOK_END_OF_FILE; /* New token. */ - loc->line = s->line; - loc->column = s->column; + s->token_line = s->line; + s->token_column = s->column; /* Operators and punctuation. */ if (chr(s, '!')) return TOK_BANG; @@ -220,8 +125,7 @@ skip_more_whitespace_and_comments: val->string.len++; } if (val->string.len == 0) { - scanner_error1(s, loc, - "unexpected character after \'$\'; expected name"); + scanner_err(s, "unexpected character after \'$\'; expected name"); return TOK_ERROR; } return TOK_GROUP_NAME; @@ -238,7 +142,7 @@ skip_more_whitespace_and_comments: return TOK_IDENTIFIER; } - scanner_error1(s, loc, "unrecognized token"); + scanner_err(s, "unrecognized token"); return TOK_ERROR; } @@ -330,7 +234,6 @@ struct matcher { struct xkb_context *ctx; /* Input.*/ struct rule_names rmlvo; - struct location loc; union lvalue val; struct scanner scanner; darray(struct group) groups; @@ -410,10 +313,8 @@ matcher_free(struct matcher *m) free(m); } -#define matcher_error1(matcher, msg) \ - scanner_error1(&(matcher)->scanner, &(matcher)->loc, msg) -#define matcher_error(matcher, fmt, ...) \ - scanner_error(&(matcher)->scanner, &(matcher)->loc, fmt, __VA_ARGS__) +#define matcher_err(matcher, fmt, ...) \ + scanner_err(&(matcher)->scanner, fmt, ## __VA_ARGS__) static void matcher_group_start_new(struct matcher *m, struct sval name) @@ -474,19 +375,15 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident) /* Not found. */ if (mlvo >= _MLVO_NUM_ENTRIES) { - matcher_error(m, - "invalid mapping: %.*s is not a valid value here; " - "ignoring rule set", - ident.len, ident.start); + matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set", + ident.len, ident.start); m->mapping.skip = true; return; } - if (m->mapping.defined_mlvo_mask & (1 << mlvo)) { - matcher_error(m, - "invalid mapping: %.*s appears twice on the same line; " - "ignoring rule set", - mlvo_sval.len, mlvo_sval.start); + if (m->mapping.defined_mlvo_mask & (1u << mlvo)) { + matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set", + mlvo_sval.len, mlvo_sval.start); m->mapping.skip = true; return; } @@ -497,10 +394,8 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident) int consumed = extract_layout_index(ident.start + mlvo_sval.len, ident.len - mlvo_sval.len, &idx); if ((int) (ident.len - mlvo_sval.len) != consumed) { - matcher_error(m, - "invalid mapping:\" %.*s\" may only be followed by a valid group index; " - "ignoring rule set", - mlvo_sval.len, mlvo_sval.start); + matcher_err(m, "invalid mapping: \"%.*s\" may only be followed by a valid group index; ignoring rule set", + mlvo_sval.len, mlvo_sval.start); m->mapping.skip = true; return; } @@ -512,17 +407,15 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident) m->mapping.variant_idx = idx; } else { - matcher_error(m, - "invalid mapping: \"%.*s\" cannot be followed by a group index; " - "ignoring rule set", - mlvo_sval.len, mlvo_sval.start); + matcher_err(m, "invalid mapping: \"%.*s\" cannot be followed by a group index; ignoring rule set", + mlvo_sval.len, mlvo_sval.start); m->mapping.skip = true; return; } } m->mapping.mlvo_at_pos[m->mapping.num_mlvo] = mlvo; - m->mapping.defined_mlvo_mask |= 1 << mlvo; + m->mapping.defined_mlvo_mask |= 1u << mlvo; m->mapping.num_mlvo++; } @@ -541,25 +434,21 @@ matcher_mapping_set_kccgst(struct matcher *m, struct sval ident) /* Not found. */ if (kccgst >= _KCCGST_NUM_ENTRIES) { - matcher_error(m, - "invalid mapping: %.*s is not a valid value here; " - "ignoring rule set", - ident.len, ident.start); + matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set", + ident.len, ident.start); m->mapping.skip = true; return; } - if (m->mapping.defined_kccgst_mask & (1 << kccgst)) { - matcher_error(m, - "invalid mapping: %.*s appears twice on the same line; " - "ignoring rule set", - kccgst_sval.len, kccgst_sval.start); + if (m->mapping.defined_kccgst_mask & (1u << kccgst)) { + matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set", + kccgst_sval.len, kccgst_sval.start); m->mapping.skip = true; return; } m->mapping.kccgst_at_pos[m->mapping.num_kccgst] = kccgst; - m->mapping.defined_kccgst_mask |= 1 << kccgst; + m->mapping.defined_kccgst_mask |= 1u << kccgst; m->mapping.num_kccgst++; } @@ -567,16 +456,12 @@ static void matcher_mapping_verify(struct matcher *m) { if (m->mapping.num_mlvo == 0) { - matcher_error1(m, - "invalid mapping: must have at least one value on the left hand side; " - "ignoring rule set"); + matcher_err(m, "invalid mapping: must have at least one value on the left hand side; ignoring rule set"); goto skip; } if (m->mapping.num_kccgst == 0) { - matcher_error1(m, - "invalid mapping: must have at least one value on the right hand side; " - "ignoring rule set"); + matcher_err(m, "invalid mapping: must have at least one value on the right hand side; ignoring rule set"); goto skip; } @@ -585,7 +470,7 @@ matcher_mapping_verify(struct matcher *m) * See the "Notes" section in the overview above. */ - if (m->mapping.defined_mlvo_mask & (1 << MLVO_LAYOUT)) { + if (m->mapping.defined_mlvo_mask & (1u << MLVO_LAYOUT)) { if (m->mapping.layout_idx == XKB_LAYOUT_INVALID) { if (darray_size(m->rmlvo.layouts) > 1) goto skip; @@ -597,7 +482,7 @@ matcher_mapping_verify(struct matcher *m) } } - if (m->mapping.defined_mlvo_mask & (1 << MLVO_VARIANT)) { + if (m->mapping.defined_mlvo_mask & (1u << MLVO_VARIANT)) { if (m->mapping.variant_idx == XKB_LAYOUT_INVALID) { if (darray_size(m->rmlvo.variants) > 1) goto skip; @@ -627,9 +512,7 @@ matcher_rule_set_mlvo_common(struct matcher *m, struct sval ident, enum mlvo_match_type match_type) { if (m->rule.num_mlvo_values + 1 > m->mapping.num_mlvo) { - matcher_error1(m, - "invalid rule: has more values than the mapping line; " - "ignoring rule"); + matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule"); m->rule.skip = true; return; } @@ -661,9 +544,7 @@ static void matcher_rule_set_kccgst(struct matcher *m, struct sval ident) { if (m->rule.num_kccgst_values + 1 > m->mapping.num_kccgst) { - matcher_error1(m, - "invalid rule: has more values than the mapping line; " - "ignoring rule"); + matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule"); m->rule.skip = true; return; } @@ -720,20 +601,10 @@ static bool append_expanded_kccgst_value(struct matcher *m, darray_char *to, struct sval value) { - const size_t original_size = darray_size(*to); const char *s = value.start; - - /* - * Appending bar to foo -> foo (not an error if this happens) - * Appending +bar to foo -> foo+bar - * Appending bar to +foo -> bar+foo - * Appending +bar to +foo -> +foo+bar - */ - if (!darray_empty(*to) && s[0] != '+' && s[0] != '|') { - if (darray_item(*to, 0) == '+' || darray_item(*to, 0) == '|') - darray_prepend_items_nullterminate(*to, value.start, value.len); - return true; - } + darray_char expanded = darray_new(); + char ch; + bool expanded_plus, to_plus; /* * Some ugly hand-lexing here, but going through the scanner is more @@ -743,12 +614,12 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to, enum rules_mlvo mlv; xkb_layout_index_t idx; char pfx, sfx; - struct sval expanded; + struct sval expanded_value; /* Check if that's a start of an expansion. */ if (s[i] != '%') { /* Just a normal character. */ - darray_append_items_nullterminate(*to, &s[i++], 1); + darray_appends_nullterminate(expanded, &s[i++], 1); continue; } if (++i >= value.len) goto error; @@ -777,9 +648,7 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to, int consumed; if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) { - matcher_error1(m, - "invalid index in %%-expansion; " - "may only index layout or variant"); + matcher_err(m, "invalid index in %%-expansion; may only index layout or variant"); goto error; } @@ -795,46 +664,65 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to, } /* Get the expanded value. */ - expanded.len = 0; + expanded_value.len = 0; if (mlv == MLVO_LAYOUT) { if (idx != XKB_LAYOUT_INVALID && idx < darray_size(m->rmlvo.layouts) && darray_size(m->rmlvo.layouts) > 1) - expanded = darray_item(m->rmlvo.layouts, idx); + expanded_value = darray_item(m->rmlvo.layouts, idx); else if (idx == XKB_LAYOUT_INVALID && darray_size(m->rmlvo.layouts) == 1) - expanded = darray_item(m->rmlvo.layouts, 0); + expanded_value = darray_item(m->rmlvo.layouts, 0); } else if (mlv == MLVO_VARIANT) { if (idx != XKB_LAYOUT_INVALID && idx < darray_size(m->rmlvo.variants) && darray_size(m->rmlvo.variants) > 1) - expanded = darray_item(m->rmlvo.variants, idx); + expanded_value = darray_item(m->rmlvo.variants, idx); else if (idx == XKB_LAYOUT_INVALID && darray_size(m->rmlvo.variants) == 1) - expanded = darray_item(m->rmlvo.variants, 0); + expanded_value = darray_item(m->rmlvo.variants, 0); } else if (mlv == MLVO_MODEL) { - expanded = m->rmlvo.model; + expanded_value = m->rmlvo.model; } /* If we didn't get one, skip silently. */ - if (expanded.len <= 0) + if (expanded_value.len <= 0) continue; if (pfx != 0) - darray_append_items_nullterminate(*to, &pfx, 1); - darray_append_items_nullterminate(*to, expanded.start, expanded.len); + darray_appends_nullterminate(expanded, &pfx, 1); + darray_appends_nullterminate(expanded, + expanded_value.start, expanded_value.len); if (sfx != 0) - darray_append_items_nullterminate(*to, &sfx, 1); + darray_appends_nullterminate(expanded, &sfx, 1); } + /* + * Appending bar to foo -> foo (not an error if this happens) + * Appending +bar to foo -> foo+bar + * Appending bar to +foo -> bar+foo + * Appending +bar to +foo -> +foo+bar + */ + + ch = (darray_empty(expanded) ? '\0' : darray_item(expanded, 0)); + expanded_plus = (ch == '+' || ch == '|'); + ch = (darray_empty(*to) ? '\0' : darray_item(*to, 0)); + to_plus = (ch == '+' || ch == '|'); + + if (expanded_plus || darray_empty(*to)) + darray_appends_nullterminate(*to, expanded.item, expanded.size); + else if (to_plus) + darray_prepends_nullterminate(*to, expanded.item, expanded.size); + + darray_free(expanded); return true; error: - matcher_error1(m, "invalid %%-expansion in value; not used"); - darray_resize(*to, original_size); + darray_free(expanded); + matcher_err(m, "invalid %%-expansion in value; not used"); return false; } @@ -843,9 +731,7 @@ matcher_rule_verify(struct matcher *m) { if (m->rule.num_mlvo_values != m->mapping.num_mlvo || m->rule.num_kccgst_values != m->mapping.num_kccgst) { - matcher_error1(m, - "invalid rule: must have same number of values as mapping line;" - "ignoring rule"); + matcher_err(m, "invalid rule: must have same number of values as mapping line; ignoring rule"); m->rule.skip = true; } } @@ -907,7 +793,7 @@ matcher_rule_apply_if_matches(struct matcher *m) static enum rules_token gettok(struct matcher *m) { - return lex(&m->scanner, &m->val, &m->loc); + return lex(&m->scanner, &m->val); } static bool @@ -1068,7 +954,7 @@ finish: return true; state_error: - matcher_error1(m, "unexpected token"); + matcher_err(m, "unexpected token"); error: return false; } @@ -1091,12 +977,13 @@ xkb_components_from_rules(struct xkb_context *ctx, ret = map_file(file, &string, &size); if (!ret) { - log_err(ctx, "Couldn't read rules file: %s\n", strerror(errno)); + log_err(ctx, "Couldn't read rules file \"%s\": %s\n", + path, strerror(errno)); goto err_file; } matcher = matcher_new(ctx, rmlvo); - ret = matcher_match(matcher, string, size, rmlvo->rules, out); + ret = matcher_match(matcher, string, size, path, out); if (!ret) log_err(ctx, "No components returned from XKB rules \"%s\"\n", path); matcher_free(matcher); diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h b/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h deleted file mode 100644 index 7e21b00662..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef XKBCOMP_SCANNER_UTILS_H -#define XKBCOMP_SCANNER_UTILS_H - -/* Point to some substring in the file; used to avoid copying. */ -struct sval { - const char *start; - unsigned int len; -}; -typedef darray(struct sval) darray_sval; - -static inline bool -svaleq(struct sval s1, struct sval s2) -{ - return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0; -} - -static inline bool -svaleq_prefix(struct sval s1, struct sval s2) -{ - return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0; -} - -struct scanner { - const char *s; - size_t pos; - size_t len; - char buf[1024]; - size_t buf_pos; - int line, column; - /* The line/column of the start of the current token. */ - int token_line, token_column; - const char *file_name; - struct xkb_context *ctx; -}; - -static inline void -scanner_init(struct scanner *s, struct xkb_context *ctx, - const char *string, size_t len, const char *file_name) -{ - s->s = string; - s->len = len; - s->pos = 0; - s->line = s->column = 1; - s->token_line = s->token_column = 1; - s->file_name = file_name; - s->ctx = ctx; -} - -static inline char -peek(struct scanner *s) -{ - return s->pos < s->len ? s->s[s->pos] : '\0'; -} - -static inline bool -eof(struct scanner *s) -{ - return s->pos >= s->len; -} - -static inline bool -eol(struct scanner *s) -{ - return peek(s) == '\n'; -} - -static inline char -next(struct scanner *s) -{ - if (eof(s)) - return '\0'; - if (eol(s)) { - s->line++; - s->column = 1; - } - else { - s->column++; - } - return s->s[s->pos++]; -} - -static inline bool -chr(struct scanner *s, char ch) -{ - if (peek(s) != ch) - return false; - s->pos++; s->column++; - return true; -} - -static inline bool -str(struct scanner *s, const char *string, size_t len) -{ - if (s->len - s->pos < len) - return false; - if (strncasecmp(s->s + s->pos, string, len) != 0) - return false; - s->pos += len; s->column += len; - return true; -} - -#define lit(s, literal) str(s, literal, sizeof(literal) - 1) - -static inline bool -buf_append(struct scanner *s, char ch) -{ - if (s->buf_pos + 1 >= sizeof(s->buf)) - return false; - s->buf[s->buf_pos++] = ch; - return true; -} - -static inline bool -oct(struct scanner *s, uint8_t *out) -{ - int i; - for (i = 0, *out = 0; peek(s) >= '0' && peek(s) <= '7' && i < 3; i++) - *out = *out * 8 + next(s) - '0'; - return i > 0; -} - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c index 48df488547..9f200bbec4 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c @@ -23,27 +23,6 @@ #include "xkbcomp-priv.h" #include "parser-priv.h" -#include "scanner-utils.h" - -static void -scanner_log(enum xkb_log_level level, struct scanner *s, const char *msg) -{ - xkb_log(s->ctx, level, 0, "%s:%d:%d: %s\n", s->file_name, - s->token_line, s->token_column, msg); -} - -int -scanner_error(struct scanner *s, const char *msg) -{ - scanner_log(XKB_LOG_LEVEL_ERROR, s, msg); - return ERROR_TOK; -} - -void -scanner_warn(struct scanner *s, const char *msg) -{ - scanner_log(XKB_LOG_LEVEL_WARNING, s, msg); -} static bool number(struct scanner *s, int64_t *out, int *out_tok) @@ -123,11 +102,13 @@ skip_more_whitespace_and_comments: buf_append(s, next(s)); } } - if (!buf_append(s, '\0') || !chr(s, '\"')) - return scanner_error(s, "unterminated string literal"); + if (!buf_append(s, '\0') || !chr(s, '\"')) { + scanner_err(s, "unterminated string literal"); + return ERROR_TOK; + } yylval->str = strdup(s->buf); if (!yylval->str) - return scanner_error(s, "scanner out of memory"); + return ERROR_TOK; return STRING; } @@ -135,8 +116,10 @@ skip_more_whitespace_and_comments: if (chr(s, '<')) { while (is_graph(peek(s)) && peek(s) != '>') buf_append(s, next(s)); - if (!buf_append(s, '\0') || !chr(s, '>')) - return scanner_error(s, "unterminated key name literal"); + if (!buf_append(s, '\0') || !chr(s, '>')) { + scanner_err(s, "unterminated key name literal"); + return ERROR_TOK; + } /* Empty key name literals are allowed. */ yylval->sval = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1); return KEYNAME; @@ -165,27 +148,32 @@ skip_more_whitespace_and_comments: s->buf_pos = 0; while (is_alnum(peek(s)) || peek(s) == '_') buf_append(s, next(s)); - if (!buf_append(s, '\0')) - return scanner_error(s, "identifier too long"); + if (!buf_append(s, '\0')) { + scanner_err(s, "identifier too long"); + return ERROR_TOK; + } /* Keyword. */ - tok = keyword_to_token(s->buf); + tok = keyword_to_token(s->buf, s->buf_pos - 1); if (tok != -1) return tok; yylval->str = strdup(s->buf); if (!yylval->str) - return scanner_error(s, "scanner out of memory"); + return ERROR_TOK; return IDENT; } /* Number literal (hexadecimal / decimal / float). */ if (number(s, &yylval->num, &tok)) { - if (tok == ERROR_TOK) - return scanner_error(s, "malformed number literal"); + if (tok == ERROR_TOK) { + scanner_err(s, "malformed number literal"); + return ERROR_TOK; + } return tok; } - return scanner_error(s, "unrecognized token"); + scanner_err(s, "unrecognized token"); + return ERROR_TOK; } XkbFile * diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c index 56cce431da..bd7f73d4f1 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c @@ -125,12 +125,11 @@ ClearGroupInfo(GroupInfo *groupi) static void CopyGroupInfo(GroupInfo *to, const GroupInfo *from) { - xkb_level_index_t j; to->defined = from->defined; to->type = from->type; darray_init(to->levels); darray_copy(to->levels, from->levels); - for (j = 0; j < darray_size(to->levels); j++) + for (xkb_level_index_t j = 0; j < darray_size(to->levels); j++) if (darray_item(from->levels, j).num_syms > 1) darray_item(to->levels, j).u.syms = memdup(darray_item(from->levels, j).u.syms, @@ -480,7 +479,6 @@ static void MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, enum merge_mode merge) { - unsigned int i; KeyInfo *keyi; ModMapEntry *mm; xkb_atom_t *group_name; @@ -498,7 +496,7 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, group_names_in_both = MIN(darray_size(into->group_names), darray_size(from->group_names)); - for (i = 0; i < group_names_in_both; i++) { + for (xkb_layout_index_t i = 0; i < group_names_in_both; i++) { if (!darray_item(from->group_names, i)) continue; @@ -511,16 +509,28 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, darray_foreach_from(group_name, from->group_names, group_names_in_both) darray_append(into->group_names, *group_name); - darray_foreach(keyi, from->keys) { - keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge); - if (!AddKeySymbols(into, keyi, false)) - into->errorCount++; + if (darray_empty(into->keys)) { + into->keys = from->keys; + darray_init(from->keys); + } + else { + darray_foreach(keyi, from->keys) { + keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge); + if (!AddKeySymbols(into, keyi, false)) + into->errorCount++; + } } - darray_foreach(mm, from->modmaps) { - mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge); - if (!AddModMapEntry(into, mm)) - into->errorCount++; + if (darray_empty(into->modmaps)) { + into->modmaps = from->modmaps; + darray_init(from->modmaps); + } + else { + darray_foreach(mm, from->modmaps) { + mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge); + if (!AddModMapEntry(into, mm)) + into->errorCount++; + } } } @@ -633,8 +643,6 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, xkb_layout_index_t ndx; GroupInfo *groupi; xkb_level_index_t nLevels; - xkb_level_index_t i; - int j; if (!GetGroupIndex(info, keyi, arrayNdx, SYMBOLS, &ndx)) return false; @@ -669,7 +677,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, groupi->defined |= GROUP_FIELD_SYMS; - for (i = 0; i < nLevels; i++) { + for (xkb_level_index_t i = 0; i < nLevels; i++) { unsigned int sym_index; struct xkb_level *leveli = &darray_item(groupi->levels, i); @@ -678,7 +686,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, if (leveli->num_syms > 1) leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms)); - for (j = 0; j < leveli->num_syms; j++) { + for (unsigned j = 0; j < leveli->num_syms; j++) { xkb_keysym_t keysym = darray_item(value->keysym_list.syms, sym_index + j); @@ -701,7 +709,6 @@ static bool AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, ExprDef *value) { - unsigned int i; xkb_layout_index_t ndx; GroupInfo *groupi; unsigned int nActs; @@ -742,7 +749,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, groupi->defined |= GROUP_FIELD_ACTS; act = value->unary.child; - for (i = 0; i < nActs; i++) { + for (unsigned i = 0; i < nActs; i++) { union xkb_action *toAct = &darray_item(groupi->levels, i).action; if (!HandleActionDef(act, info->keymap, toAct, info->actions)) @@ -772,19 +779,20 @@ static bool SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, ExprDef *arrayNdx, ExprDef *value) { - bool ok = true; struct xkb_context *ctx = info->keymap->ctx; if (istreq(field, "type")) { xkb_layout_index_t ndx; xkb_atom_t val; - if (!ExprResolveString(ctx, value, &val)) - log_vrb(ctx, 1, + if (!ExprResolveString(ctx, value, &val)) { + log_err(ctx, "The type field of a key symbol map must be a string; " "Ignoring illegal type definition\n"); + return false; + } - if (arrayNdx == NULL) { + if (!arrayNdx) { keyi->default_type = val; keyi->defined |= KEY_FIELD_DEFAULT_TYPE; } @@ -803,32 +811,33 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, darray_item(keyi->groups, ndx).defined |= GROUP_FIELD_TYPE; } } - else if (istreq(field, "symbols")) + else if (istreq(field, "symbols")) { return AddSymbolsToKey(info, keyi, arrayNdx, value); - else if (istreq(field, "actions")) + } + else if (istreq(field, "actions")) { return AddActionsToKey(info, keyi, arrayNdx, value); + } else if (istreq(field, "vmods") || istreq(field, "virtualmods") || istreq(field, "virtualmodifiers")) { xkb_mod_mask_t mask; - ok = ExprResolveModMask(info->keymap, value, MOD_VIRT, &mask); - if (ok) { - keyi->vmodmap = mask; - keyi->defined |= KEY_FIELD_VMODMAP; - } - else { - log_err(info->keymap->ctx, + if (!ExprResolveModMask(info->keymap, value, MOD_VIRT, &mask)) { + log_err(ctx, "Expected a virtual modifier mask, found %s; " "Ignoring virtual modifiers definition for key %s\n", expr_op_type_to_string(value->expr.op), KeyInfoText(info, keyi)); + return false; } + + keyi->vmodmap = mask; + keyi->defined |= KEY_FIELD_VMODMAP; } else if (istreq(field, "locking") || istreq(field, "lock") || istreq(field, "locks")) { - log_err(info->keymap->ctx, + log_vrb(ctx, 1, "Key behaviors not supported; " "Ignoring locking specification for key %s\n", KeyInfoText(info, keyi)); @@ -836,14 +845,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, else if (istreq(field, "radiogroup") || istreq(field, "permanentradiogroup") || istreq(field, "allownone")) { - log_err(info->keymap->ctx, + log_vrb(ctx, 1, "Radio groups not supported; " "Ignoring radio group specification for key %s\n", KeyInfoText(info, keyi)); } else if (istreq_prefix("overlay", field) || istreq_prefix("permanentoverlay", field)) { - log_err(info->keymap->ctx, + log_vrb(ctx, 1, "Overlays not supported; " "Ignoring overlay specification for key %s\n", KeyInfoText(info, keyi)); @@ -853,14 +862,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, istreq(field, "repeat")) { unsigned int val; - ok = ExprResolveEnum(ctx, value, &val, repeatEntries); - if (!ok) { - log_err(info->keymap->ctx, + if (!ExprResolveEnum(ctx, value, &val, repeatEntries)) { + log_err(ctx, "Illegal repeat setting for %s; " "Non-boolean repeat setting ignored\n", KeyInfoText(info, keyi)); return false; } + keyi->repeat = val; keyi->defined |= KEY_FIELD_REPEAT; } @@ -869,18 +878,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, bool set; if (!ExprResolveBoolean(ctx, value, &set)) { - log_err(info->keymap->ctx, + log_err(ctx, "Illegal groupsWrap setting for %s; " "Non-boolean value ignored\n", KeyInfoText(info, keyi)); return false; } - if (set) - keyi->out_of_range_group_action = RANGE_WRAP; - else - keyi->out_of_range_group_action = RANGE_SATURATE; - + keyi->out_of_range_group_action = (set ? RANGE_WRAP : RANGE_SATURATE); keyi->defined |= KEY_FIELD_GROUPINFO; } else if (istreq(field, "groupsclamp") || @@ -888,18 +893,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, bool set; if (!ExprResolveBoolean(ctx, value, &set)) { - log_err(info->keymap->ctx, + log_err(ctx, "Illegal groupsClamp setting for %s; " "Non-boolean value ignored\n", KeyInfoText(info, keyi)); return false; } - if (set) - keyi->out_of_range_group_action = RANGE_SATURATE; - else - keyi->out_of_range_group_action = RANGE_WRAP; - + keyi->out_of_range_group_action = (set ? RANGE_SATURATE : RANGE_WRAP); keyi->defined |= KEY_FIELD_GROUPINFO; } else if (istreq(field, "groupsredirect") || @@ -907,7 +908,7 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, xkb_layout_index_t grp; if (!ExprResolveGroup(ctx, value, &grp)) { - log_err(info->keymap->ctx, + log_err(ctx, "Illegal group index for redirect of key %s; " "Definition with non-integer group ignored\n", KeyInfoText(info, keyi)); @@ -919,17 +920,17 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, keyi->defined |= KEY_FIELD_GROUPINFO; } else { - log_err(info->keymap->ctx, + log_err(ctx, "Unknown field %s in a symbol interpretation; " "Definition ignored\n", field); - ok = false; + return false; } - return ok; + return true; } -static int +static bool SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value) { xkb_layout_index_t group, group_to_use; @@ -979,16 +980,16 @@ SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value) return true; } -static int +static bool HandleGlobalVar(SymbolsInfo *info, VarDef *stmt) { const char *elem, *field; ExprDef *arrayNdx; bool ret; - if (ExprResolveLhs(info->keymap->ctx, stmt->name, &elem, &field, - &arrayNdx) == 0) - return 0; /* internal error, already reported */ + if (!ExprResolveLhs(info->keymap->ctx, stmt->name, &elem, &field, &arrayNdx)) + return false; + if (elem && istreq(elem, "key")) { ret = SetSymbolsField(info, &info->default_key, field, arrayNdx, stmt->value); @@ -1098,16 +1099,15 @@ SetExplicitGroup(SymbolsInfo *info, KeyInfo *keyi) return true; } -static int +static bool HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt) { KeyInfo keyi; - xkb_layout_index_t i; keyi = info->default_key; darray_init(keyi.groups); darray_copy(keyi.groups, info->default_key.groups); - for (i = 0; i < darray_size(keyi.groups); i++) + for (xkb_layout_index_t i = 0; i < darray_size(keyi.groups); i++) CopyGroupInfo(&darray_item(keyi.groups, i), &darray_item(info->default_key.groups, i)); keyi.merge = stmt->merge; @@ -1134,7 +1134,6 @@ HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt) static bool HandleModMapDef(SymbolsInfo *info, ModMapDef *def) { - ExprDef *key; ModMapEntry tmp; xkb_mod_index_t ndx; bool ok; @@ -1153,7 +1152,7 @@ HandleModMapDef(SymbolsInfo *info, ModMapDef *def) tmp.modifier = ndx; tmp.merge = def->merge; - for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) { + for (ExprDef *key = def->keys; key; key = (ExprDef *) key->common.next) { xkb_keysym_t sym; if (key->expr.op == EXPR_VALUE && @@ -1198,7 +1197,7 @@ HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge) ok = HandleGlobalVar(info, (VarDef *) stmt); break; case STMT_VMOD: - ok = HandleVModDef(info->keymap, (VModDef *) stmt); + ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge); break; case STMT_MODMAP: ok = HandleModMapDef(info, (ModMapDef *) stmt); @@ -1518,7 +1517,7 @@ CopyModMapDef(SymbolsInfo *info, ModMapEntry *entry) } } - key->modmap |= (1 << entry->modifier); + key->modmap |= (1u << entry->modifier); return true; } diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/types.c b/src/3rdparty/xkbcommon/src/xkbcomp/types.c index 5b7ccbb4db..7708da3882 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/types.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/types.c @@ -30,111 +30,6 @@ #include "expr.h" #include "include.h" -/* - * The xkb_types section - * ===================== - * This section is the second to be processesed, after xkb_keycodes. - * However, it is completely independent and could have been the first - * to be processed (it does not refer to specific keys as specified in - * the xkb_keycodes section). - * - * This section defines key types, which, given a key and a keyboard - * state (i.e. modifier state and group), determine the shift level to - * be used in translating the key to keysyms. These types are assigned - * to each group in each key, in the xkb_symbols section. - * - * Key types are called this way because, in a way, they really describe - * the "type" of the key (or more correctly, a specific group of the - * key). For example, an ordinary keymap will provide a type called - * "KEYPAD", which consists of two levels, with the second level being - * chosen according to the state of the Num Lock (or Shift) modifiers. - * Another example is a type called "ONE_LEVEL", which is usually - * assigned to keys such as Escape; these have just one level and are - * not affected by the modifier state. Yet more common examples are - * "TWO_LEVEL" (with Shift choosing the second level), "ALPHABETIC" - * (where Caps Lock may also choose the second level), etc. - * - * Type definitions - * ---------------- - * Statements of the form: - * type "FOUR_LEVEL" { ... } - * - * The above would create a new type named "FOUR_LEVEL". - * The body of the definition may include statements of the following - * forms: - * - * - level_name statements (mandatory for each level in the type): - * level_name[Level1] = "Base"; - * - * Gives each level in this type a descriptive name. It isn't used - * for any thing. - * Note: A level may be specified as Level[1-8] or just a number (can - * be more than 8). - * - * - modifiers statement (mandatory, should be specified only once): - * modifiers = Shift+Lock+LevelThree; - * - * A mask of real and virtual modifiers. These are the only modifiers - * being considered when matching the modifier state against the type. - * The other modifiers, whether active or not, are masked out in the - * calculation. - * - * - map entry statements (should have at least as many mappings as there - * are levels in the type): - * map[Shift+LevelThree] = Level4; - * - * If the active modifiers, masked with the type's modifiers (as stated - * above), match (i.e. equal) the modifiers inside the map[] statement, - * then the level in the right hand side is chosen. For example, in the - * above, if in the current keyboard state the Shift and LevelThree - * modifiers are active, while the Lock modifier is not, then the - * keysym(s) in the 4th level of the group will be returned to the - * user. - * - * - preserve statements: - * map[Shift+Lock+LevelThree] = Level5; - * preserve[Shift+Lock+LevelThree] = Lock; - * - * When a map entry matches the active modifiers and the level it - * specified is chosen, then these modifiers are said to be "consumed"; - * for example, in a simple US keymap where the "g" key is assigned an - * ordinary ALPHABETIC key type, if the Lock (Caps Lock) modifier is - * active and the key is pressed, then a "G" keysym is produced (as - * opposed to lower-case "g"). This is because the type definition has - * a map entry like the following: - * map[Lock] = Level2; - * And as such the Lock modifier is consumed. This information is - * relevant for applications which further process the modifiers, - * since by then the consumed modifiers have already "done their part" - * and should be masked out. - * - * However, sometimes even if a modifier is actually used to choose - * the shift level (as Lock above), it should *not* be reported as - * consumed, for various reasons. In this case, a preserve[] statement - * can be used to augment the map entry. The modifiers inside the square - * brackets should match one of the map[] statements in the type. The - * right hand side should consists of modifiers from the left hand - * side; these modifiers are then "preserved" and not reported as - * consumed. - * - * Virtual modifier statements - * --------------------------- - * Statements of the form: - * virtual_modifiers LControl; - * - * Can appear in the xkb_types, xkb_compat, xkb_symbols sections. - * TODO - * - * Effect on keymap - * ---------------- - * After all of the xkb_types sections have been compiled, the following - * members of struct xkb_keymap are finalized: - * struct xkb_key_type *types; - * unsigned int num_types; - * char *types_section_name; - * TODO: virtual modifiers. - */ - enum type_field { TYPE_FIELD_MASK = (1 << 0), TYPE_FIELD_MAP = (1 << 1), @@ -287,10 +182,16 @@ MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from, from->name = NULL; } - darray_foreach(type, from->types) { - type->merge = (merge == MERGE_DEFAULT ? type->merge : merge); - if (!AddKeyType(into, type, false)) - into->errorCount++; + if (darray_empty(into->types)) { + into->types = from->types; + darray_init(from->types); + } + else { + darray_foreach(type, from->types) { + type->merge = (merge == MERGE_DEFAULT ? type->merge : merge); + if (!AddKeyType(into, type, false)) + into->errorCount++; + } } } @@ -738,7 +639,7 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge) ok = true; break; case STMT_VMOD: - ok = HandleVModDef(info->keymap, (VModDef *) stmt); + ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge); break; default: log_err(info->keymap->ctx, diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c index 206e1624e6..86e7bec786 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c @@ -30,27 +30,64 @@ #include "vmod.h" bool -HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt) +HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt, + enum merge_mode merge) { xkb_mod_index_t i; - const struct xkb_mod *mod; + struct xkb_mod *mod; + xkb_mod_mask_t mapping; struct xkb_mod new; - if (stmt->value) - log_err(keymap->ctx, - "Support for setting a value in a virtual_modifiers statement has been removed; " - "Value ignored\n"); + merge = (merge == MERGE_DEFAULT ? stmt->merge : merge); + + if (stmt->value) { + /* + * This is a statement such as 'virtualModifiers NumLock = Mod1'; + * it sets the vmod-to-real-mod[s] mapping directly instead of going + * through modifier_map or some such. + */ + if (!ExprResolveModMask(keymap, stmt->value, MOD_REAL, &mapping)) { + log_err(keymap->ctx, + "Declaration of %s ignored\n", + xkb_atom_text(keymap->ctx, stmt->name)); + return false; + } + } + else { + mapping = 0; + } darray_enumerate(i, mod, keymap->mods) { if (mod->name == stmt->name) { - if (mod->type == MOD_VIRT) + if (mod->type != MOD_VIRT) { + log_err(keymap->ctx, + "Can't add a virtual modifier named \"%s\"; " + "there is already a non-virtual modifier with this name! Ignored\n", + xkb_atom_text(keymap->ctx, mod->name)); + return false; + } + + if (mod->mapping == mapping) return true; - log_err(keymap->ctx, - "Can't add a virtual modifier named \"%s\"; " - "there is already a non-virtual modifier with this name! Ignored\n", - xkb_atom_text(keymap->ctx, mod->name)); - return false; + if (mod->mapping != 0) { + xkb_mod_mask_t use, ignore; + + use = (merge == MERGE_OVERRIDE ? mapping : mod->mapping); + ignore = (merge == MERGE_OVERRIDE ? mod->mapping : mapping); + + log_warn(keymap->ctx, + "Virtual modifier %s defined multiple times; " + "Using %s, ignoring %s\n", + xkb_atom_text(keymap->ctx, stmt->name), + ModMaskText(keymap, use), + ModMaskText(keymap, ignore)); + + mapping = use; + } + + mod->mapping = mapping; + return true; } } @@ -62,7 +99,7 @@ HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt) } new.name = stmt->name; - new.mapping = 0; + new.mapping = mapping; new.type = MOD_VIRT; darray_append(keymap->mods, new); return true; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h index 991550735f..1ba59f73cd 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h @@ -28,6 +28,7 @@ #define XKBCOMP_VMOD_H bool -HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt); +HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt, + enum merge_mode merge); #endif diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h index f96e4c806f..299732fdc3 100644 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h +++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h @@ -91,4 +91,8 @@ #define xkb_state_get_map(state) xkb_state_get_keymap(state) +/* Not needed anymore, since there's NO_FLAGS. */ +#define XKB_MAP_COMPILE_PLACEHOLDER XKB_KEYMAP_COMPILE_NO_FLAGS +#define XKB_MAP_COMPILE_NO_FLAGS XKB_KEYMAP_COMPILE_NO_FLAGS + #endif diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h index 4ec9b649c7..d9e2a4f11a 100644 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h +++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h @@ -27,6 +27,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @file * libxkbcommon-x11 API - Additional X11 support for xkbcommon. @@ -163,4 +167,8 @@ xkb_x11_state_new_from_device(struct xkb_keymap *keymap, /** @} */ +#ifdef __cplusplus +} /* extern "C" */ #endif + +#endif /* _XKBCOMMON_X11_H */ diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h index cc9262ff89..36251db443 100644 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h +++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h @@ -305,26 +305,60 @@ typedef uint32_t xkb_led_mask_t; /** * Names to compile a keymap with, also known as RMLVO. * - * These names together are the primary identifier for a keymap. - * If any of the members is NULL or an empty string (""), a default value is - * used. It is recommended to use the system default by passing NULL for - * unspecified values, instead of providing your own defaults. + * The names are the common configuration values by which a user picks + * a keymap. + * + * If the entire struct is NULL, then each field is taken to be NULL. + * You should prefer passing NULL instead of choosing your own defaults. */ struct xkb_rule_names { - /** The rules file to use. The rules file describes how to interpret - * the values of the model, layout, variant and options fields. */ + /** + * The rules file to use. The rules file describes how to interpret + * the values of the model, layout, variant and options fields. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_RULES environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *rules; - /** The keyboard model by which to interpret keycodes and LEDs. */ + /** + * The keyboard model by which to interpret keycodes and LEDs. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_MODEL environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *model; - /** A comma separated list of layouts (languages) to include in the - * keymap. */ + /** + * A comma separated list of layouts (languages) to include in the + * keymap. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_LAYOUT environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *layout; - /** A comma separated list of variants, one per layout, which may - * modify or augment the respective layout in various ways. */ + /** + * A comma separated list of variants, one per layout, which may + * modify or augment the respective layout in various ways. + * + * If NULL or the empty string "", and a default value is also used + * for the layout, a default value is used. Otherwise no variant is + * used. + * If the XKB_DEFAULT_VARIANT environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *variant; - /** A comma separated list of options, through which the user specifies - * non-layout related preferences, like which key combinations are used - * for switching layouts, or which key is the Compose key. */ + /** + * A comma separated list of options, through which the user specifies + * non-layout related preferences, like which key combinations are used + * for switching layouts, or which key is the Compose key. + * + * If NULL, a default value is used. If the empty string "", no + * options are used. + * If the XKB_DEFAULT_OPTIONS environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *options; }; @@ -399,6 +433,11 @@ xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags); * @returns The number of bytes written to the buffer (including the * terminating byte). If the keysym does not have a Unicode * representation, returns 0. If the buffer is too small, returns -1. + * + * Prefer not to use this function on keysyms obtained from an + * xkb_state. In this case, use xkb_state_key_get_utf8() instead. + * + * @sa xkb_state_key_get_utf8() */ int xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size); @@ -409,6 +448,11 @@ xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size); * @returns The Unicode/UTF-32 representation of keysym, which is also * compatible with UCS-4. If the keysym does not have a Unicode * representation, returns 0. + * + * Prefer not to use this function on keysyms obtained from an + * xkb_state. In this case, use xkb_state_key_get_utf32() instead. + * + * @sa xkb_state_key_get_utf32() */ uint32_t xkb_keysym_to_utf32(xkb_keysym_t keysym); @@ -681,9 +725,7 @@ xkb_context_set_log_fn(struct xkb_context *context, /** Flags for keymap compilation. */ enum xkb_keymap_compile_flags { /** Do not apply any flags. */ - XKB_MAP_COMPILE_NO_FLAGS = 0, - /** Apparently you can't have empty enums. What a drag. */ - XKB_MAP_COMPILE_PLACEHOLDER = 0 + XKB_KEYMAP_COMPILE_NO_FLAGS = 0 }; /** @@ -692,13 +734,8 @@ enum xkb_keymap_compile_flags { * The primary keymap entry point: creates a new XKB keymap from a set of * RMLVO (Rules + Model + Layouts + Variants + Options) names. * - * You should almost certainly be using this and nothing else to create - * keymaps. - * * @param context The context in which to create the keymap. - * @param names The RMLVO names to use. In xkbcommon versions prior - * to 0.2.1, this field must be non-NULL. In later - * versions, passing NULL will use the default keymap. + * @param names The RMLVO names to use. See xkb_rule_names. * @param flags Optional flags for the keymap, or 0. * * @returns A keymap compiled according to the RMLVO names, or NULL if @@ -1159,6 +1196,13 @@ enum xkb_state_component { * is pressed twice, it should be released twice; etc. Otherwise (e.g. due * to missed input events), situations like "stuck modifiers" may occur. * + * This function is often used in conjunction with the function + * xkb_state_key_get_syms() (or xkb_state_key_get_one_sym()), for example, + * when handling a key event. In this case, you should prefer to get the + * keysyms *before* updating the key, such that the keysyms reported for + * the key event are not affected by the event itself. This is the + * conventional behavior. + * * @returns A mask of state components that have changed as a result of * the update. If nothing in the state has changed, returns 0. * @@ -1234,6 +1278,44 @@ int xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t key, const xkb_keysym_t **syms_out); +/** + * Get the Unicode/UTF-8 string obtained from pressing a particular key + * in a given keyboard state. + * + * @param[in] state The keyboard state object. + * @param[in] key The keycode of the key. + * @param[out] buffer A buffer to write the string into. + * @param[in] size Size of the buffer. + * + * @warning If the buffer passed is too small, the string is truncated + * (though still NUL-terminated). + * + * @returns The number of bytes required for the string, excluding the + * NUL byte. If there is nothing to write, returns 0. + * + * You may check if truncation has occurred by comparing the return value + * with the size of @p buffer, similarly to the snprintf(3) function. + * You may safely pass NULL and 0 to @p buffer and @p size to find the + * required size (without the NUL-byte). + * + * @memberof xkb_state + */ +int +xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t key, + char *buffer, size_t size); + +/** + * Get the Unicode/UTF-32 codepoint obtained from pressing a particular + * key in a a given keyboard state. + * + * @returns The UTF-32 representation for the key, if it consists of only + * a single codepoint. Otherwise, returns 0. + * + * @memberof xkb_state + */ +uint32_t +xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t key); + /** * Get the single keysym obtained from pressing a particular key in a * given keyboard state. @@ -1485,6 +1567,7 @@ xkb_state_mod_indices_are_active(struct xkb_state *state, * index is not valid in the keymap, returns -1. * * @sa xkb_state_mod_mask_remove_consumed() + * @sa xkb_state_key_get_consumed_mods() * @memberof xkb_state */ int @@ -1504,6 +1587,17 @@ xkb_mod_mask_t xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t key, xkb_mod_mask_t mask); +/** + * Get the mask of modifiers consumed by translating a given key. + * + * @returns a mask of the consumed modifiers. + * + * @sa xkb_state_mod_index_is_consumed() + * @memberof xkb_state + */ +xkb_mod_mask_t +xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t key); + /** * Test whether a layout is active in a given keyboard state by name. * diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index aefd9655ed..1acd466aeb 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -48,10 +48,7 @@ #include #ifndef QT_NO_XKB -// note: extern won't be needed from libxkbcommon 0.4.1 and above -extern "C" { #include -} #endif #include -- cgit v1.2.3 From 6ad458bc93162753e448eea28499e778e2946d2c Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 31 Mar 2014 17:13:20 +0200 Subject: Fix regression in key handling. libxkbcommon 0.4.1 added two new functions, xkb_state_key_get_utf{8,32}(). They combine the operations of xkb_state_key_get_syms() and xkb_keysym_to_utf{8,32}(). The xkb_state_key_get_utf{8,32}() functions now apply Control transformation: when the Control modifier is active, the string is converted to an appropriate control character. This matches the behavior of libX11's XLookupString(3), and is required by the XKB specification: http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier Task-number: QTBUG-36281 Change-Id: Ib45f45d801291c171640600384107a35d7d56b9b Reviewed-by: Ran Benita Reviewed-by: Lars Knoll --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 19 ++++++++----------- src/plugins/platforms/xcb/qxcbkeyboard.h | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 73cfb76bfc..4ee1cb4305 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -853,7 +853,7 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const return QList(); QList result; - int baseQtKey = keysymToQtKey(sym, modifiers, keysymToUnicode(sym)); + int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode())); result += (baseQtKey + modifiers); // The base key is _always_ valid, of course xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift"); @@ -900,7 +900,7 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const continue; Qt::KeyboardModifiers mods = modifiers & ~neededMods; - qtKey = keysymToQtKey(sym, mods, keysymToUnicode(sym)); + qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode())); if (qtKey == baseQtKey) continue; @@ -1316,7 +1316,8 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod } Qt::KeyboardModifiers modifiers = translateModifiers(state); - QString string = keysymToUnicode(sym); + + QString string = lookupString(xkb_state, code); int count = string.size(); string.truncate(count); @@ -1379,16 +1380,12 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod } } -QString QXcbKeyboard::keysymToUnicode(xcb_keysym_t sym) const +QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const { QByteArray chars; - int bytes; - chars.resize(7); - bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size()); - if (bytes == -1) - qWarning("QXcbKeyboard::handleKeyEvent - buffer too small"); - chars.resize(bytes-1); - + chars.resize(1 + xkb_state_key_get_utf8(state, code, 0, 0)); + // equivalent of XLookupString + xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); return QString::fromUtf8(chars); } diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 1acd466aeb..ce27785ae1 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -86,7 +86,7 @@ protected: void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time); void resolveMaskConflicts(); - QString keysymToUnicode(xcb_keysym_t sym) const; + QString lookupString(struct xkb_state *state, xcb_keycode_t code) const; int keysymToQtKey(xcb_keysym_t keysym) const; int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const; void printKeymapError(const char *error) const; -- cgit v1.2.3 From f412f2b5ee58e3919a8cd514c8fcfa75444ae976 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 2 Apr 2014 17:16:33 +0200 Subject: move platform toolset retrieval to VcprojGenerator In a subsequent commit we will need access to more information of the project object. This is merely a refactoring. Change-Id: I40e501d037eb7d0295e1057e7b86e404e88e6ca3 Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/msbuild_objectmodel.cpp | 26 +------------------------- qmake/generators/win32/msbuild_objectmodel.h | 1 - qmake/generators/win32/msvc_objectmodel.h | 1 + qmake/generators/win32/msvc_vcproj.cpp | 25 +++++++++++++++++++++++++ qmake/generators/win32/msvc_vcproj.h | 1 + 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 51cb73f0ce..feef587ee6 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -1779,8 +1779,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool) xml << tag("PropertyGroup") << attrTag("Condition", generateCondition(tool)) << attrTag("Label", "Configuration") - << attrTagS(_PlatformToolSet, platformToolSetVersion(tool.CompilerVersion, - tool.WinPhone)) + << attrTagS(_PlatformToolSet, tool.PlatformToolSet) << attrTagS(_OutputDirectory, tool.OutputDirectory) << attrTagT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage) << attrTagT(_BuildBrowserInformation, tool.BuildBrowserInformation) @@ -2193,27 +2192,4 @@ QString VCXProjectWriter::generateCondition(const VCConfiguration &config) return QStringLiteral("'$(Configuration)|$(Platform)'=='") + config.Name + QLatin1Char('\''); } -QString VCXProjectWriter::platformToolSetVersion(const DotNET version, bool winphoneBuild) -{ - // The PlatformToolset string corresponds to the name of a directory in - // $(VCTargetsPath)\Platforms\{Win32,x64,...}\PlatformToolsets - // e.g. v90, v100, v110, v110_xp, v120_CTP_Nov, v120, or WindowsSDK7.1 - - // This environment variable may be set by a commandline build - // environment such as the Windows SDK command prompt - QByteArray envVar = qgetenv("PlatformToolset"); - if (!envVar.isEmpty()) - return envVar; - - switch (version) - { - case NET2012: - return winphoneBuild ? "v110_wp80" : "v110"; - case NET2013: - return "v120"; - default: - return QString(); - } -} - QT_END_NAMESPACE diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h index 2f02e66eb9..8ccb4b8859 100644 --- a/qmake/generators/win32/msbuild_objectmodel.h +++ b/qmake/generators/win32/msbuild_objectmodel.h @@ -184,7 +184,6 @@ private: static void outputFileConfigs(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter, const VCFilterFile &info, const QString &filtername); static bool outputFileConfig(VCFilter &filter, XmlOutput &xml, XmlOutput &xmlFilter, const QString &filename, const QString &filtername, bool fileAllreadyAdded); static QString generateCondition(const VCConfiguration &config); - static QString platformToolSetVersion(const DotNET version, bool winphoneBuild); friend class XTreeNode; friend class XFlatNode; diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 0aa5736d2a..ac96d55de1 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -901,6 +901,7 @@ public: QString OutputDirectory; QString PrimaryOutput; QString ProgramDatabase; + QString PlatformToolSet; triState RegisterOutput; useOfATL UseOfATL; useOfMfc UseOfMfc; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index ce9dc6d9ec..86a9d518f2 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -384,6 +384,29 @@ QUuid VcprojGenerator::increaseUUID(const QUuid &id) return result; } +QString VcprojGenerator::retrievePlatformToolSet() const +{ + // The PlatformToolset string corresponds to the name of a directory in + // $(VCTargetsPath)\Platforms\{Win32,x64,...}\PlatformToolsets + // e.g. v90, v100, v110, v110_xp, v120_CTP_Nov, v120, or WindowsSDK7.1 + + // This environment variable may be set by a commandline build + // environment such as the Windows SDK command prompt + QByteArray envVar = qgetenv("PlatformToolset"); + if (!envVar.isEmpty()) + return envVar; + + switch (vcProject.Configuration.CompilerVersion) + { + case NET2012: + return vcProject.Configuration.WinPhone ? "v110_wp80" : "v110"; + case NET2013: + return "v120"; + default: + return QString(); + } +} + ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash &projLookup, QHash &projGuids, QHash &extraSubdirs, @@ -969,6 +992,8 @@ void VcprojGenerator::initConfiguration() if (!conf.OutputDirectory.endsWith("\\")) conf.OutputDirectory += '\\'; if (conf.CompilerVersion >= NET2010) { + conf.PlatformToolSet = retrievePlatformToolSet(); + // The target name could have been changed. conf.PrimaryOutput = project->first("TARGET").toQString(); if ( !conf.PrimaryOutput.isEmpty() && !project->first("TARGET_VERSION_EXT").isEmpty() && project->isActiveConfig("shared")) diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 4a25d11766..7dcd9f72df 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -144,6 +144,7 @@ private: QHash &subdirProjectLookup, const ProStringList &allDependencies = ProStringList()); QUuid increaseUUID(const QUuid &id); + QString retrievePlatformToolSet() const; friend class VCFilter; }; -- cgit v1.2.3 From 10a0ac759e26e27751ae96d02eb1e260ab371194 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 2 Apr 2014 16:56:15 +0200 Subject: Windows XP target support for MSVC >= 2012 To enable windows xp support, we must do two things: 1. linker flag must be /SUBSYSTEM:CONSOLE,5.01 or /SUBSYSTEM:WINDOWS,5.01. For x64, the version is 5.02. 2. Do not use Windows Kit 8. Win SDK v7.1A is recommended. Prepend the right include paths and lib paths to INCLUDE and LIB before building. The Windows XP target support is enabled by passing "-target xp" to configure. Task-number: QTBUG-29939 Change-Id: I84c8439606cc2a9d27d64947702846faa4f1e4a2 Reviewed-by: Lucas Wang Reviewed-by: Oswald Buddenhagen --- mkspecs/features/win32/console.prf | 4 +++- mkspecs/features/win32/qt_config.prf | 10 ++++++++++ mkspecs/features/win32/windows.prf | 4 +++- mkspecs/win32-msvc2012/qmake.conf | 4 ++-- mkspecs/win32-msvc2013/qmake.conf | 4 ++-- qmake/generators/win32/msvc_vcproj.cpp | 10 ++++++++-- src/corelib/io/qfilesystemengine_win.cpp | 4 ++-- src/corelib/kernel/qeventdispatcher_win.cpp | 4 ++-- tools/configure/configureapp.cpp | 29 ++++++++++++++++++++++++++++- 9 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 mkspecs/features/win32/qt_config.prf diff --git a/mkspecs/features/win32/console.prf b/mkspecs/features/win32/console.prf index 8a1725d648..568d1b1eb5 100644 --- a/mkspecs/features/win32/console.prf +++ b/mkspecs/features/win32/console.prf @@ -1,4 +1,6 @@ CONFIG -= windows contains(TEMPLATE, ".*app") { - QMAKE_LFLAGS += $$QMAKE_LFLAGS_CONSOLE $$QMAKE_LFLAGS_EXE + QMAKE_LFLAGS += \ + $$replace(QMAKE_LFLAGS_CONSOLE, @QMAKE_SUBSYSTEM_SUFFIX@, $$QMAKE_SUBSYSTEM_SUFFIX) \ + $$QMAKE_LFLAGS_EXE } diff --git a/mkspecs/features/win32/qt_config.prf b/mkspecs/features/win32/qt_config.prf new file mode 100644 index 0000000000..49b4c79431 --- /dev/null +++ b/mkspecs/features/win32/qt_config.prf @@ -0,0 +1,10 @@ +load(qt_config) + +equals(QMAKE_TARGET_OS, xp) { + # http://blogs.msdn.com/b/vcblog/archive/2012/10/08/10357555.aspx?PageIndex=3 + equals(QT_ARCH, x86_64) { + QMAKE_SUBSYSTEM_SUFFIX = ,5.02 + } else { + QMAKE_SUBSYSTEM_SUFFIX = ,5.01 + } +} diff --git a/mkspecs/features/win32/windows.prf b/mkspecs/features/win32/windows.prf index 82e0ebe1b5..6d8289d949 100644 --- a/mkspecs/features/win32/windows.prf +++ b/mkspecs/features/win32/windows.prf @@ -1,6 +1,8 @@ CONFIG -= console contains(TEMPLATE, ".*app"){ - QMAKE_LFLAGS += $$QMAKE_LFLAGS_WINDOWS $$QMAKE_LFLAGS_EXE + QMAKE_LFLAGS += \ + $$replace(QMAKE_LFLAGS_WINDOWS, @QMAKE_SUBSYSTEM_SUFFIX@, $$QMAKE_SUBSYSTEM_SUFFIX) \ + $$QMAKE_LFLAGS_EXE mingw:DEFINES += QT_NEEDS_QMAIN qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) { diff --git a/mkspecs/win32-msvc2012/qmake.conf b/mkspecs/win32-msvc2012/qmake.conf index 18ffc27711..2cedc46807 100644 --- a/mkspecs/win32-msvc2012/qmake.conf +++ b/mkspecs/win32-msvc2012/qmake.conf @@ -70,8 +70,8 @@ QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO QMAKE_LFLAGS_DEBUG = /DEBUG -QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE -QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS +QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@ +QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@ QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_LTCG = /LTCG diff --git a/mkspecs/win32-msvc2013/qmake.conf b/mkspecs/win32-msvc2013/qmake.conf index ad46a2fb72..6e0bd0b214 100644 --- a/mkspecs/win32-msvc2013/qmake.conf +++ b/mkspecs/win32-msvc2013/qmake.conf @@ -70,8 +70,8 @@ QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO QMAKE_LFLAGS_DEBUG = /DEBUG -QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE -QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS +QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@ +QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@ QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_LTCG = /LTCG diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 86a9d518f2..03a41fd1bc 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -396,12 +396,18 @@ QString VcprojGenerator::retrievePlatformToolSet() const if (!envVar.isEmpty()) return envVar; + QString suffix; + if (vcProject.Configuration.WinPhone) + suffix = "_wp80"; + else if (project->first("QMAKE_TARGET_OS") == "xp") + suffix = "_xp"; + switch (vcProject.Configuration.CompilerVersion) { case NET2012: - return vcProject.Configuration.WinPhone ? "v110_wp80" : "v110"; + return QStringLiteral("v110") + suffix; case NET2013: - return "v120"; + return QStringLiteral("v120") + suffix; default: return QString(); } diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 7741eb4c1e..8e3bacd6b7 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -606,7 +606,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) // FILE_INFO_BY_HANDLE_CLASS has been extended by FileIdInfo = 18 as of VS2012. typedef enum { Q_FileIdInfo = 18 } Q_FILE_INFO_BY_HANDLE_CLASS; -# if defined(Q_CC_MINGW) || (defined(Q_CC_MSVC) && _MSC_VER < 1700) +# if defined(Q_CC_MINGW) || (defined(Q_CC_MSVC) && (_MSC_VER < 1700 || WINVER <= 0x0601)) // MinGW-64 defines FILE_ID_128 as of gcc-4.8.1 along with FILE_SUPPORTS_INTEGRITY_STREAMS # if !(defined(Q_CC_MINGW) && defined(FILE_SUPPORTS_INTEGRITY_STREAMS)) @@ -619,7 +619,7 @@ typedef struct _FILE_ID_INFO { ULONGLONG VolumeSerialNumber; FILE_ID_128 FileId; } FILE_ID_INFO, *PFILE_ID_INFO; -# endif // if defined (Q_CC_MINGW) || (defined(Q_CC_MSVC) && _MSC_VER < 1700)) +# endif // if defined (Q_CC_MINGW) || (defined(Q_CC_MSVC) && (_MSC_VER < 1700 || WINVER <= 0x0601)) // File ID for Windows up to version 7. static inline QByteArray fileId(HANDLE handle) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index dfb897c0fd..64ad2ff0d3 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -435,10 +435,10 @@ static inline UINT inputTimerMask() UINT result = QS_TIMER | QS_INPUT | QS_RAWINPUT; // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8. -#if defined(_MSC_VER) && _MSC_VER >= 1700 +#if WINVER > 0x0601 if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) result &= ~(QS_TOUCH | QS_POINTER); -#endif // _MSC_VER >= 1700 +#endif // WINVER > 0x0601 return result; } diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 176fe3092f..49c7fc9618 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -482,7 +482,18 @@ void Configure::parseCmdLine() else if (configCmdLine.at(i) == "-force-asserts") { dictionary[ "FORCE_ASSERTS" ] = "yes"; } - + else if (configCmdLine.at(i) == "-target") { + ++i; + if (i == argCount) + break; + const QString option = configCmdLine.at(i); + if (option != "xp") { + cout << "ERROR: invalid argument for -target option" << endl; + dictionary["DONE"] = "error"; + return; + } + dictionary["TARGET_OS"] = option; + } else if (configCmdLine.at(i) == "-platform") { ++i; if (i == argCount) @@ -1817,6 +1828,10 @@ bool Configure::displayHelp() desc( "-platform ", "The operating system and compiler you are building on.\n(default %QMAKESPEC%)\n"); desc( "-xplatform ", "The operating system and compiler you are cross compiling to.\n"); desc( "", "See the README file for a list of supported operating systems and compilers.\n", false, ' '); + + desc("TARGET_OS", "*", "-target", "Set target OS version. Currently the only valid value is 'xp' for targeting Windows XP.\n" + "MSVC >= 2012 targets Windows Vista by default.\n"); + desc( "-sysroot ", "Sets as the target compiler's and qmake's sysroot and also sets pkg-config paths."); desc( "-no-gcc-sysroot", "When using -sysroot, it disables the passing of --sysroot to the compiler.\n"); @@ -2497,6 +2512,12 @@ bool Configure::verifyConfiguration() << "files such as headers and libraries." << endl; prompt = true; } +#if WINVER > 0x0601 + if (dictionary["TARGET_OS"] == "xp") { + cout << "WARNING: Cannot use Windows Kit 8 to build Qt for Windows XP.\n" + "WARNING: Windows SDK v7.1A is recommended.\n"; + } +#endif if (dictionary["DIRECT2D"] == "yes" && !checkAvailability("DIRECT2D")) { cout << "WARNING: To be able to build the Direct2D platform plugin you will" << endl @@ -3331,6 +3352,10 @@ void Configure::generateQConfigPri() << "}" << endl; } + const QString targetOS = dictionary.value("TARGET_OS"); + if (!targetOS.isEmpty()) + configStream << "QMAKE_TARGET_OS = " << targetOS << endl; + if (!dictionary["QMAKE_RPATHDIR"].isEmpty()) configStream << "QMAKE_RPATHDIR += " << formatPath(dictionary["QMAKE_RPATHDIR"]) << endl; @@ -3574,6 +3599,8 @@ void Configure::displayConfig() sout << "QMAKESPEC..................." << dictionary[ "XQMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl; else sout << "QMAKESPEC..................." << dictionary[ "QMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl; + if (!dictionary["TARGET_OS"].isEmpty()) + sout << "Target OS..................." << dictionary["TARGET_OS"] << endl; sout << "Architecture................" << dictionary["QT_ARCH"] << ", features:" << dictionary["QT_CPU_FEATURES"] << endl; sout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"] -- cgit v1.2.3 From 826ab028a8c24b115286d251938396ca1de71b56 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 3 Apr 2014 11:54:10 +0200 Subject: vcxproj generator: append version suffix only to library targets Task-number: QTBUG-38066 Change-Id: I2f1635f2cb34acb388c380fc2fc3fbe4df04bb03 Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/msvc_vcproj.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 03a41fd1bc..ac258e2841 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1002,8 +1002,10 @@ void VcprojGenerator::initConfiguration() // The target name could have been changed. conf.PrimaryOutput = project->first("TARGET").toQString(); - if ( !conf.PrimaryOutput.isEmpty() && !project->first("TARGET_VERSION_EXT").isEmpty() && project->isActiveConfig("shared")) + if (!conf.PrimaryOutput.isEmpty() && project->first("TEMPLATE") == "vclib" + && project->isActiveConfig("shared")) { conf.PrimaryOutput.append(project->first("TARGET_VERSION_EXT").toQString()); + } } if (conf.CompilerVersion >= NET2012) { -- cgit v1.2.3 From af97b73d390e890523fc88e502e693fe29febfa5 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 1 Apr 2014 17:44:29 +0200 Subject: do not define QT_NO_STYLE_S60 on Windows This isn't needed anymore since quite a while. Change-Id: I80a99f988a917af5b8c64865ec7e73e519978740 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 49c7fc9618..bb09a19e55 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3472,10 +3472,6 @@ void Configure::generateConfigfiles() if (dictionary["STYLE_WINDOWSXP"] != "yes" && dictionary["STYLE_WINDOWSVISTA"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSXP"; if (dictionary["STYLE_WINDOWSVISTA"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSVISTA"; - - // ### We still need the QT_NO_STYLE_S60 define for compiling Qt. Remove later! - qconfigList += "QT_NO_STYLE_S60"; - if (dictionary["STYLE_WINDOWSCE"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSCE"; if (dictionary["STYLE_WINDOWSMOBILE"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSMOBILE"; if (dictionary["STYLE_GTK"] != "yes") qconfigList += "QT_NO_STYLE_GTK"; -- cgit v1.2.3 From 078f83a761dae61b3f10f80eb330b9a39755d2ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 31 Mar 2014 12:20:01 +0200 Subject: Compile: remove "register" keyword in MD5Transform "register" is usually ignored by the compiler and is deprecated in C++11 [-Werror,-Wdeprecated-register] Change-Id: I3a10f2128e4a4574b2cd3861bddbbd4ba6a3683f Reviewed-by: Konstantin Ritt --- src/3rdparty/md5/md5.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/md5/md5.cpp b/src/3rdparty/md5/md5.cpp index 16871e6626..cc69b56213 100644 --- a/src/3rdparty/md5/md5.cpp +++ b/src/3rdparty/md5/md5.cpp @@ -161,7 +161,7 @@ MD5Final(struct MD5Context *ctx, md5byte digest[16]) static void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) { - register UWORD32 a, b, c, d; + UWORD32 a, b, c, d; a = buf[0]; b = buf[1]; -- cgit v1.2.3 From 7b7c37ab94ae78ac3ba0e7ffa269bcdc7a0ad706 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 24 Mar 2014 15:32:14 -0700 Subject: Add a benchmark test for QCryptographicHash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some quick benchmarks against GNU coreutils 8.21 and OpenSSL 1.0.1e (time in µs; time for coreutils and OpenSSL include the loading of the executable): Qt Coreutils OpenSSL n SHA-1 SHA-224 SHA-512 SHA-1 SHA-224 SHA-512 SHA-1 SHA-224 SHA-512 0 0 0 0 717 716 700 2532 2553 2522 64k 120 484 381 927 1074 966 2618 2782 2694 Diff 120 484 381 210 358 266 86 229 172 The numbers for Qt are pretty stable and vary very little; the numbers for the other two vary quite a bit, since they involve launching and executing separate processes. We can take the lesson that we're in the same ballpark for SHA-1 and we should investigate whether our SHA2 implementation is sufficiently optimized. Change-Id: Ib081d002ed57c4f43741eca45ff5cd13b97b6276 Reviewed-by: Richard J. Moore --- .../corelib/tools/qcryptographichash/main.cpp | 186 +++++++++++++++++++++ .../qcryptographichash/qcryptographichash.pro | 5 + tests/benchmarks/corelib/tools/tools.pro | 1 + 3 files changed, 192 insertions(+) create mode 100644 tests/benchmarks/corelib/tools/qcryptographichash/main.cpp create mode 100644 tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp new file mode 100644 index 0000000000..b82b2ef991 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Intel Corporation +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +#ifdef Q_OS_WINCE +// no C89 time() on Windows CE: +// http://blogs.msdn.com/b/cenet/archive/2006/04/29/time-h-on-windows-ce.aspx +uint time(void *) +{ + return uint(-1); +} +#endif + +class tst_bench_QCryptographicHash : public QObject +{ + Q_OBJECT + QByteArray blockOfData; + +public: + tst_bench_QCryptographicHash(); + +private Q_SLOTS: + void hash_data(); + void hash(); + void addData_data() { hash_data(); } + void addData(); + void addDataChunked_data() { hash_data(); } + void addDataChunked(); +}; + +const int MaxCryptoAlgorithm = QCryptographicHash::Sha3_512; +const int MaxBlockSize = 65536; + +const char *algoname(int i) +{ + switch (QCryptographicHash::Algorithm(i)) { + case QCryptographicHash::Md4: + return "md4-"; + case QCryptographicHash::Md5: + return "md5-"; + case QCryptographicHash::Sha1: + return "sha1-"; + case QCryptographicHash::Sha224: + return "sha2_224-"; + case QCryptographicHash::Sha256: + return "sha2_256-"; + case QCryptographicHash::Sha384: + return "sha2_384-"; + case QCryptographicHash::Sha512: + return "sha2_512-"; + case QCryptographicHash::Sha3_224: + return "sha3_224-"; + case QCryptographicHash::Sha3_256: + return "sha3_256-"; + case QCryptographicHash::Sha3_384: + return "sha3_384-"; + case QCryptographicHash::Sha3_512: + return "sha3_512-"; + } + Q_UNREACHABLE(); + return 0; +} + +tst_bench_QCryptographicHash::tst_bench_QCryptographicHash() + : blockOfData(MaxBlockSize, Qt::Uninitialized) +{ +#ifdef Q_OS_UNIX + QFile urandom("/dev/urandom"); + if (urandom.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) { + QCOMPARE(urandom.read(blockOfData.data(), blockOfData.size()), qint64(MaxBlockSize)); + } else +#endif + { + qsrand(time(NULL)); + for (int i = 0; i < MaxBlockSize; ++i) + blockOfData[i] = qrand(); + } +} + +void tst_bench_QCryptographicHash::hash_data() +{ + QTest::addColumn("algorithm"); + QTest::addColumn("data"); + + static const int datasizes[] = { 0, 1, 64, 65, 512, 4095, 4096, 4097, 65536 }; + for (uint i = 0; i < sizeof(datasizes)/sizeof(datasizes[0]); ++i) { + Q_ASSERT(datasizes[i] < MaxBlockSize); + QByteArray data = QByteArray::fromRawData(blockOfData.constData(), datasizes[i]); + + for (int algo = QCryptographicHash::Md4; algo <= MaxCryptoAlgorithm; ++algo) + QTest::newRow(algoname(algo) + QByteArray::number(datasizes[i])) << algo << data; + } +} + +void tst_bench_QCryptographicHash::hash() +{ + QFETCH(int, algorithm); + QFETCH(QByteArray, data); + + QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); + QBENCHMARK { + QCryptographicHash::hash(data, algo); + } +} + +void tst_bench_QCryptographicHash::addData() +{ + QFETCH(int, algorithm); + QFETCH(QByteArray, data); + + QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); + QCryptographicHash hash(algo); + QBENCHMARK { + hash.reset(); + hash.addData(data); + hash.result(); + } +} + +void tst_bench_QCryptographicHash::addDataChunked() +{ + QFETCH(int, algorithm); + QFETCH(QByteArray, data); + + QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); + QCryptographicHash hash(algo); + QBENCHMARK { + hash.reset(); + + // add the data in chunks of 64 bytes + for (int i = 0; i < data.size() / 64; ++i) + hash.addData(data.constData() + 64 * i, 64); + hash.addData(data.constData() + data.size() / 64 * 64, data.size() % 64); + + hash.result(); + } +} + +QTEST_APPLESS_MAIN(tst_bench_QCryptographicHash) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro b/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro new file mode 100644 index 0000000000..9c55de8b47 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro @@ -0,0 +1,5 @@ +TARGET = tst_bench_qcryptographichash +CONFIG -= debug app_bundle +CONFIG += release console +QT = core testlib +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro index 3cc269202a..08570aadb9 100644 --- a/tests/benchmarks/corelib/tools/tools.pro +++ b/tests/benchmarks/corelib/tools/tools.pro @@ -4,6 +4,7 @@ SUBDIRS = \ containers-sequential \ qbytearray \ qcontiguouscache \ + qcryptographichash \ qdatetime \ qlist \ qlocale \ -- cgit v1.2.3 From 00d5e3c917826540ad804c25b9e209fa6e4ec195 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Thu, 3 Apr 2014 20:29:49 +0200 Subject: update bundled sqlite to 3.8.4.3 The "Fixed CE build of sqlite3" patch is preserved in this change. (ea70ec8711af45128d63634a01dfc4c1a51ac331) Change-Id: I163a4bcc92f47838c8203d8f5d78bbdcb0c1fd84 Reviewed-by: Friedemann Kleint --- src/3rdparty/sqlite/sqlite3.c | 8 ++++---- src/3rdparty/sqlite/sqlite3.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index f8a10149bc..27b5beac12 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.8.4.2. By combining all the individual C code files into this +** version 3.8.4.3. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -222,9 +222,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.8.4.2" +#define SQLITE_VERSION "3.8.4.3" #define SQLITE_VERSION_NUMBER 3008004 -#define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e" +#define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -115273,7 +115273,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ for(; kp1!=pLevel->iTabCur ) continue; if( pOp->opcode==OP_Column ){ - pOp->opcode = OP_SCopy; + pOp->opcode = OP_Copy; pOp->p1 = pOp->p2 + pTabItem->regResult; pOp->p2 = pOp->p3; pOp->p3 = 0; diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index d0d676afae..0884ebad0e 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -107,9 +107,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.8.4.2" +#define SQLITE_VERSION "3.8.4.3" #define SQLITE_VERSION_NUMBER 3008004 -#define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e" +#define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" /* ** CAPI3REF: Run-Time Library Version Numbers -- cgit v1.2.3 From cb8e33fc0fb16a30d572c15985d0913a754dfc1c Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 2 Apr 2014 17:04:03 +0200 Subject: Doc: fix link to changed topic title in Qt Creator Manual The "Creating an Android Application" tutorial was adapted to also apply to iOS and renamed as "Creating a Mobile Application". The page name (HTML) was changed as well. Change-Id: I445a258e21242b3c19b8fd83b35d24514ffc94cc Reviewed-by: Sergio Ahumada Reviewed-by: Jerome Pasion --- doc/global/externalsites/qtcreator.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/global/externalsites/qtcreator.qdoc b/doc/global/externalsites/qtcreator.qdoc index 2edb3769fd..30e65034fc 100644 --- a/doc/global/externalsites/qtcreator.qdoc +++ b/doc/global/externalsites/qtcreator.qdoc @@ -468,8 +468,8 @@ \title Qt Creator: Adding Debuggers */ /*! - \externalpage http://qt-project.org/doc/qtcreator/creator-android-app-tutorial.html - \title Qt Creator: Creating an Android Application + \externalpage http://qt-project.org/doc/qtcreator/creator-mobile-app-tutorial.html + \title Qt Creator: Creating a Mobile Application */ /*! \externalpage http://qt-project.org/doc/qtcreator/creator-diff-editor.html -- cgit v1.2.3 From 82d2d9b3ccc90d512f259ced0e5ef45cd0d536fd Mon Sep 17 00:00:00 2001 From: Jorgen Lind Date: Thu, 3 Apr 2014 12:06:40 +0200 Subject: Fixup QGuiApplication::sync to flush the QWSI queue Change-Id: If4cedeb886e912f622a66b2b3374d6260cffc32a Reviewed-by: Laszlo Agocs --- src/gui/kernel/qguiapplication.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a19eebfb7c..f96bdc39a6 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3002,6 +3002,7 @@ void QGuiApplication::sync() && QGuiApplicationPrivate::platform_integration->hasCapability(QPlatformIntegration::SyncState)) { QGuiApplicationPrivate::platform_integration->sync(); QCoreApplication::processEvents(); + QWindowSystemInterface::flushWindowSystemEvents(); } } -- cgit v1.2.3 From d743443c04a7b83d2773bf2d8e3820626ef2d94e Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Tue, 1 Apr 2014 11:34:21 +0200 Subject: BlackBerry: Fix tst_qdialog::show{Maximized,Minimized} tests Using show() might result in showFullScreen() on some platforms, so let's use setVisible(true) which has the same effect and seems to be a more crossplatform solution. Change-Id: I712584ace2adbe73b99e620a1ae5e88ff328fffb Reviewed-by: Friedemann Kleint Reviewed-by: Fabian Bumberger --- tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index d8833e232d..c3d2c4a9e7 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -276,7 +276,7 @@ void tst_QDialog::showMaximized() QVERIFY(dialog.isMaximized()); QVERIFY(!dialog.isVisible()); - dialog.show(); + dialog.setVisible(true); QVERIFY(dialog.isMaximized()); QVERIFY(dialog.isVisible()); @@ -309,7 +309,7 @@ void tst_QDialog::showMinimized() QVERIFY(dialog.isMinimized()); QVERIFY(!dialog.isVisible()); - dialog.show(); + dialog.setVisible(true); QVERIFY(dialog.isMinimized()); QVERIFY(dialog.isVisible()); -- cgit v1.2.3 From 5947fda8fd45b424461d0b9fa8334d3a6185df72 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 3 Apr 2014 12:17:35 +0200 Subject: QNX: Fix QAbstractItemView autotest One problem was that tests expect the top-level window to have a certain size, which is not possible on BlackBerry. Another problem was that certain elements have a dpi dependent size which the task250754_fontChange test did not consider. Change-Id: I465ebe234a74d6150cdcbb7fc7e458a62155e0d0 Reviewed-by: Sergio Ahumada --- .../itemviews/qabstractitemview/tst_qabstractitemview.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 1005bf6b3c..83c4582645 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -1246,7 +1246,7 @@ void tst_QAbstractItemView::task250754_fontChange() vLayout->addWidget(&tree); QStandardItemModel *m = new QStandardItemModel(this); - for (int i=0; i<5; ++i) { + for (int i=0; i<20; ++i) { QStandardItem *item = new QStandardItem(QString("Item number %1").arg(i)); for (int j=0; j<5; ++j) { QStandardItem *child = new QStandardItem(QString("Child Item number %1").arg(j)); @@ -1256,10 +1256,11 @@ void tst_QAbstractItemView::task250754_fontChange() } tree.setModel(m); - w.resize(160, 240); // Minimum width for windows with frame on Windows 8 + tree.setHeaderHidden(true); // The header is (in certain styles) dpi dependent + w.resize(160, 300); // Minimum width for windows with frame on Windows 8 centerOnScreen(&w); moveCursorAway(&w); - w.show(); + w.showNormal(); QVERIFY(QTest::qWaitForWindowExposed(&w)); QFont font = tree.font(); font.setPixelSize(10); @@ -1579,11 +1580,16 @@ void tst_QAbstractItemView::testDelegateDestroyEditor() void tst_QAbstractItemView::testClickedSignal() { +#if defined Q_OS_BLACKBERRY + QWidget rootWindow; + rootWindow.show(); + QTest::qWaitForWindowExposed(&rootWindow); +#endif QTableWidget view(5, 5); centerOnScreen(&view); moveCursorAway(&view); - view.show(); + view.showNormal(); QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); QCOMPARE(static_cast(&view), QApplication::activeWindow()); -- cgit v1.2.3 From 11b8794456e4abb5c2068bb1ee1067fcdf79baa1 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 3 Apr 2014 12:52:19 +0200 Subject: Fix QTextEdit autotest Change-Id: I2178f1bb09f334ac518ede8f08c5b9268ea0c505 Reviewed-by: Sergio Ahumada --- tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 53c76a0da6..8695c8b29a 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -2018,6 +2018,7 @@ void tst_QTextEdit::fullWidthSelection2() QPalette myPalette; myPalette.setColor(QPalette::All, QPalette::HighlightedText, QColor(0,0,0,0)); myPalette.setColor(QPalette::All, QPalette::Highlight, QColor(239,221,85)); + myPalette.setColor(QPalette::All, QPalette::Base, QColor(255,255,255)); QTextEdit widget; widget.setPalette(myPalette); @@ -2218,7 +2219,7 @@ void tst_QTextEdit::twoSameInputMethodEvents() QInputMethodEvent event("PreEditText", attributes); QApplication::sendEvent(ed, &event); - QCOMPARE(ed->document()->firstBlock().layout()->lineCount(), 1); + QTRY_COMPARE(ed->document()->firstBlock().layout()->lineCount(), 1); QApplication::sendEvent(ed, &event); QCOMPARE(ed->document()->firstBlock().layout()->lineCount(), 1); } -- cgit v1.2.3 From ba2ea6da298bfd234af1afeaf154fa4aaefaad88 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 4 Apr 2014 09:44:07 +0200 Subject: Don't assume qt_tablet_target widget exists from one event to the next In this scenario there is a widget with a button inside, and you click the button with the tablet. The target of the event is the button, but when you click it, the parent (or ancestor) is destroyed. Commit 2bac49265efcf8faabc3756d1a3e405a3d336f68 took care of the case when the parent is a window, but it is not always a window which is being destroyed. So the approach of using a QPointer is better because it should take care of all the cases when the qt_tablet_target is destroyed during the course of a tablet event sequence. Task-number: QTBUG-36848 Task-number: QTBUG-38040 Change-Id: Ia0e861f2cb2fbc30234aa596f3a36ddd0835a9af Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qwidgetwindow.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 41a3dcc048..0031d8e965 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -58,8 +58,7 @@ QT_BEGIN_NAMESPACE Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets(); QWidget *qt_button_down = 0; // widget got last button-down -static QWidget *qt_tablet_target = 0; -static QWidget *qt_tablet_target_window = 0; +static QPointer qt_tablet_target = 0; // popup control QWidget *qt_popup_down = 0; // popup that contains the pressed widget @@ -105,10 +104,6 @@ QWidgetWindow::QWidgetWindow(QWidget *widget) QWidgetWindow::~QWidgetWindow() { - if (m_widget == qt_tablet_target_window) { - qt_tablet_target = 0; - qt_tablet_target_window = 0; - } } #ifndef QT_NO_ACCESSIBILITY @@ -791,7 +786,6 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event) widget = m_widget; qt_tablet_target = widget; - qt_tablet_target_window = m_widget; } if (qt_tablet_target) { @@ -804,10 +798,8 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event) QGuiApplication::sendSpontaneousEvent(qt_tablet_target, &ev); } - if (event->type() == QEvent::TabletRelease) { + if (event->type() == QEvent::TabletRelease) qt_tablet_target = 0; - qt_tablet_target_window = 0; - } } #endif // QT_NO_TABLETEVENT -- cgit v1.2.3 From 7d005c502bf3553ef9cab497bc6d51a83341a493 Mon Sep 17 00:00:00 2001 From: Jorgen Lind Date: Mon, 31 Mar 2014 16:03:27 +0200 Subject: Add isCreated to QOpenGLTextureBlitter Change-Id: Icb1a0354ac1caee38e3cb0cba6d7daec99d66c54 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopengltextureblitter.cpp | 6 ++++++ src/gui/opengl/qopengltextureblitter_p.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp index 9710f1677c..efe769badf 100644 --- a/src/gui/opengl/qopengltextureblitter.cpp +++ b/src/gui/opengl/qopengltextureblitter.cpp @@ -282,6 +282,12 @@ bool QOpenGLTextureBlitter::create() return true; } +bool QOpenGLTextureBlitter::isCreated() const +{ + Q_D(const QOpenGLTextureBlitter); + return d->program; +} + void QOpenGLTextureBlitter::destroy() { Q_D(QOpenGLTextureBlitter); diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter_p.h index b2ccc13391..c1dcaf5700 100644 --- a/src/gui/opengl/qopengltextureblitter_p.h +++ b/src/gui/opengl/qopengltextureblitter_p.h @@ -62,6 +62,7 @@ public: }; bool create(); + bool isCreated() const; void destroy(); void bind(); -- cgit v1.2.3 From 9ce697f2d54be6d94381c72af28dda79cbc027d4 Mon Sep 17 00:00:00 2001 From: Wolfgang Bremer Date: Thu, 3 Apr 2014 12:31:54 +0200 Subject: Rename QNX arm mkspecs to be aligned with SDP structure The current SDP uses CPUVARDIR variable to define whether x86 or armle-v7 is used. Therefore, the whole structure uses these two definitions to separate simulator and device builds. Renaming qnx-armv7le-qcc to qnx-armle-v7-qcc allows to directly use CPUVARDIR during Qt5 builds. For compatibility reasons the old folder is kept and includes the new qmake.conf. This change is similar to fe61f2d6b29cca87b46dc37c7968b2f765f670ef where we already aligned the BB10 mkspecs to the NDK structure. Change-Id: I7e1c0c2d137dc4049549233940e7f9d1c9f671f0 Reviewed-by: Andreas Holzammer Reviewed-by: Oswald Buddenhagen Reviewed-by: Fabian Bumberger --- mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h | 2 +- mkspecs/qnx-armle-v7-qcc/qmake.conf | 7 ++ mkspecs/qnx-armle-v7-qcc/qplatformdefs.h | 109 ++++++++++++++++++++++++ mkspecs/qnx-armv7le-qcc/qmake.conf | 8 +- mkspecs/qnx-armv7le-qcc/qplatformdefs.h | 71 +-------------- 5 files changed, 122 insertions(+), 75 deletions(-) create mode 100644 mkspecs/qnx-armle-v7-qcc/qmake.conf create mode 100644 mkspecs/qnx-armle-v7-qcc/qplatformdefs.h diff --git a/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h b/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h index 32becb2042..874429f634 100644 --- a/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h +++ b/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h @@ -39,4 +39,4 @@ ** ****************************************************************************/ -#include "../qnx-armv7le-qcc/qplatformdefs.h" +#include "../qnx-armle-v7-qcc/qplatformdefs.h" diff --git a/mkspecs/qnx-armle-v7-qcc/qmake.conf b/mkspecs/qnx-armle-v7-qcc/qmake.conf new file mode 100644 index 0000000000..8dd84811c1 --- /dev/null +++ b/mkspecs/qnx-armle-v7-qcc/qmake.conf @@ -0,0 +1,7 @@ +# +# qmake configuration for qnx-qcc armv7 targets +# + +include(../common/qcc-base-qnx-armv7le.conf) + +DEFINES += QT_NO_CLIPBOARD diff --git a/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h new file mode 100644 index 0000000000..2f95f0d392 --- /dev/null +++ b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2012 - 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +// Get Qt defines/settings + +#include "qglobal.h" + +// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs + +#include + +#define __STDC_CONSTANT_MACROS + +// We are hot - unistd.h should have turned on the specific APIs we requested + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +// QNX doesn't have the System V header. This is not a standard +// POSIX header, it's only documented in the Single UNIX Specification. +// The preferred POSIX compliant way to share memory is to use the functions +// in that comply with the POSIX Real Time Interface (1003.1b). +#include +#include +#include +#include +#include +#ifndef QT_NO_IPV6IFNAME +#include +#endif + +// for htonl +#include + +#define QT_USE_XOPEN_LFS_EXTENSIONS +#if !defined(__EXT_QNX__READDIR64_R) +#define QT_NO_READDIR64 +#endif +#include "../common/posix/qplatformdefs.h" +#if defined(__EXT_QNX__READDIR64_R) +#define QT_EXT_QNX_READDIR_R ::_readdir64_r +#elif defined(__EXT_QNX__READDIR_R) +#define QT_EXT_QNX_READDIR_R ::_readdir_r +#endif + +#define QT_SNPRINTF ::snprintf +#define QT_VSNPRINTF ::vsnprintf + +// QNX6 doesn't have getpagesize() +inline int getpagesize() +{ + return ::sysconf(_SC_PAGESIZE); +} + +#include + +#define QT_QWS_TEMP_DIR QString::fromLatin1(qgetenv("TMP")) + +#endif // QPLATFORMDEFS_H diff --git a/mkspecs/qnx-armv7le-qcc/qmake.conf b/mkspecs/qnx-armv7le-qcc/qmake.conf index 8dd84811c1..daae30168d 100644 --- a/mkspecs/qnx-armv7le-qcc/qmake.conf +++ b/mkspecs/qnx-armv7le-qcc/qmake.conf @@ -1,7 +1,5 @@ # -# qmake configuration for qnx-qcc armv7 targets +# deprecated, please use qnx-armle-v7-qcc instead # - -include(../common/qcc-base-qnx-armv7le.conf) - -DEFINES += QT_NO_CLIPBOARD +warning("You are using deprecated mkspecs. Please use qnx-armle-v7-qcc instead.") +include(../qnx-armle-v7-qcc/qmake.conf) diff --git a/mkspecs/qnx-armv7le-qcc/qplatformdefs.h b/mkspecs/qnx-armv7le-qcc/qplatformdefs.h index b47aecde0d..bc8f6792ab 100644 --- a/mkspecs/qnx-armv7le-qcc/qplatformdefs.h +++ b/mkspecs/qnx-armv7le-qcc/qplatformdefs.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Research In Motion Limited. +** Copyright (C) 2012 - 2014 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -39,71 +39,4 @@ ** ****************************************************************************/ -#ifndef QPLATFORMDEFS_H -#define QPLATFORMDEFS_H - -// Get Qt defines/settings - -#include "qglobal.h" - -// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs - -#include - -#define __STDC_CONSTANT_MACROS - -// We are hot - unistd.h should have turned on the specific APIs we requested - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -// QNX doesn't have the System V header. This is not a standard -// POSIX header, it's only documented in the Single UNIX Specification. -// The preferred POSIX compliant way to share memory is to use the functions -// in that comply with the POSIX Real Time Interface (1003.1b). -#include -#include -#include -#include -#include -#ifndef QT_NO_IPV6IFNAME -#include -#endif - -// for htonl -#include - -#define QT_USE_XOPEN_LFS_EXTENSIONS -#if !defined(__EXT_QNX__READDIR64_R) -#define QT_NO_READDIR64 -#endif -#include "../common/posix/qplatformdefs.h" -#if defined(__EXT_QNX__READDIR64_R) -#define QT_EXT_QNX_READDIR_R ::_readdir64_r -#elif defined(__EXT_QNX__READDIR_R) -#define QT_EXT_QNX_READDIR_R ::_readdir_r -#endif - -#define QT_SNPRINTF ::snprintf -#define QT_VSNPRINTF ::vsnprintf - -// QNX6 doesn't have getpagesize() -inline int getpagesize() -{ - return ::sysconf(_SC_PAGESIZE); -} - -#include - -#define QT_QWS_TEMP_DIR QString::fromLatin1(qgetenv("TMP")) - -#endif // QPLATFORMDEFS_H +#include "../qnx-armle-v7-qcc/qplatformdefs.h" -- cgit v1.2.3 From 758b9adccffa47a321294b0d2ff94b78f2dba7d4 Mon Sep 17 00:00:00 2001 From: aavit Date: Thu, 3 Apr 2014 12:54:47 +0200 Subject: Fix lance opengl painting test Change b94493e revealed that in the lance script rendering, at the surface_end command, cleaning up the fbo stuff and enabling the ordinary painting again was done in the wrong order. Change-Id: I358dafeffe95b25303fc2a8dc1d61384b2ca64fb Reviewed-by: Gunnar Sletta --- tests/auto/other/lancelot/paintcommands.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/auto/other/lancelot/paintcommands.cpp b/tests/auto/other/lancelot/paintcommands.cpp index 91cda9b4aa..4449b75e46 100644 --- a/tests/auto/other/lancelot/paintcommands.cpp +++ b/tests/auto/other/lancelot/paintcommands.cpp @@ -2430,11 +2430,6 @@ void PaintCommands::command_surface_end(QRegExp) if (m_type == OpenGLType || m_type == OpenGLBufferType) { #ifndef QT_NO_OPENGL QImage new_image = m_surface_glbuffer->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); - m_default_glcontext->makeCurrent(m_default_glcontext->surface()); - m_painter->drawImage(m_surface_rect, new_image); - // Flush the pipeline: - m_painter->beginNativePainting(); - m_painter->endNativePainting(); delete m_surface_glpaintdevice; m_surface_glpaintdevice = 0; @@ -2442,6 +2437,12 @@ void PaintCommands::command_surface_end(QRegExp) m_surface_glbuffer = 0; delete m_surface_glcontext; m_surface_glcontext = 0; + + m_default_glcontext->makeCurrent(m_default_glcontext->surface()); + m_painter->drawImage(m_surface_rect, new_image); + // Flush the pipeline: + m_painter->beginNativePainting(); + m_painter->endNativePainting(); #endif #ifdef Q_WS_X11 } else if (m_type == WidgetType) { -- cgit v1.2.3 From f0dbc6b37e9e9ab5bde07be09ad0dbb68c12c024 Mon Sep 17 00:00:00 2001 From: Martin Koller Date: Tue, 18 Mar 2014 23:03:12 +0100 Subject: Fix: Initialize all needed member vars Change-Id: I74b71d93e25e4b3b0c1a5766f2fbc4f71aebecbb Reviewed-by: Gunnar Sletta --- src/platformsupport/fbconvenience/qfbcursor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp index b86f5830ea..bff663c13b 100644 --- a/src/platformsupport/fbconvenience/qfbcursor.cpp +++ b/src/platformsupport/fbconvenience/qfbcursor.cpp @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE QFbCursor::QFbCursor(QFbScreen *screen) - : mScreen(screen), mCurrentRect(QRect()), mPrevRect(QRect()) + : mScreen(screen), mDirty(false), mOnScreen(false) { mGraphic = new QPlatformCursorImage(0, 0, 0, 0, 0, 0); setCursor(Qt::ArrowCursor); -- cgit v1.2.3 From 19ff7d038fbc7117d2bfddb6f2ad27b1fdd84acb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 4 Apr 2014 15:41:56 +0200 Subject: Increase tolerance for warning about QTest::qSleep() for Windows. 50% is too strict, it clutters the logs. Change-Id: Ib391064f32e39a1192e77d872cd99b7f95a5065a Reviewed-by: Ulf Hermann --- src/testlib/qtestcase.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 3ab3fcc44c..cbf479f1d2 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2878,7 +2878,12 @@ void QTest::qSleep(int ms) // requested time. qint64 requested = 1000000 * (qint64)ms; qint64 diff = timer.nsecsElapsed() - requested; - if (diff * 2 > requested || diff * 10 < -requested) { +#ifndef Q_OS_WIN + const qint64 factor = 2; // more than 50% longer +#else + const qint64 factor = 1; // Windows: 50% is quite common, warn about 100% +#endif + if (diff * factor > requested || diff * 10 < -requested) { QTestLog::warn(qPrintable( QString::fromLatin1("QTest::qSleep() should have taken %1ns, but actually took %2ns!") .arg(requested).arg(diff + requested)), __FILE__, __LINE__); -- cgit v1.2.3 From 9a4beb4d36dc0c613e59aa5d88060d521462f56c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 2 Apr 2014 14:08:29 +0200 Subject: Improve handling of temporary directories in SQL tests. Initialize directory delayed in shared code and add checks to verify that it is valid. Close attached / cloned databases to prevent locks on files and leaking temporary directories caused by SQLite: QTemporaryDir: Unable to remove "...\Temp\tst_qsqldatabase-P1XkOA" most likely due to the presence of read-only files. QTemporaryDir: Unable to remove "...\Temp\tst_qsqltablemodel-P1XkOA" most likely due to the presence of read-only files. QWARN : tst_QSql::concurrentAccess() QTemporaryDir: Unable to remove "...\Temp\tst_qsql-l0VAKJ" most likely due to the presence of read-only files. Change-Id: If85bbaed04bb1a32e427d642be332996d967f796 Reviewed-by: Andy Shaw Reviewed-by: Joerg Bornemann --- tests/auto/sql/kernel/qsql/tst_qsql.cpp | 11 +++---- tests/auto/sql/kernel/qsqldatabase/tst_databases.h | 34 ++++++++++++++++++---- .../sql/kernel/qsqldatabase/tst_qsqldatabase.cpp | 5 ++-- .../auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp | 4 +-- tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp | 4 +-- .../auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp | 4 +-- .../models/qsqlquerymodel/tst_qsqlquerymodel.cpp | 4 +-- .../tst_qsqlrelationaltablemodel.cpp | 4 +-- .../models/qsqltablemodel/tst_qsqltablemodel.cpp | 5 ++-- 9 files changed, 50 insertions(+), 25 deletions(-) diff --git a/tests/auto/sql/kernel/qsql/tst_qsql.cpp b/tests/auto/sql/kernel/qsql/tst_qsql.cpp index 24f418af26..2dcd75427b 100644 --- a/tests/auto/sql/kernel/qsql/tst_qsql.cpp +++ b/tests/auto/sql/kernel/qsql/tst_qsql.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -117,7 +117,7 @@ void tst_QSql::basicDriverTest() char *argv[] = { const_cast(QTest::currentAppName()) }; QCoreApplication app(argc, argv, false); tst_Databases dbs; - dbs.open(); + QVERIFY(dbs.open()); foreach (const QString& dbName, dbs.dbNames) { QSqlDatabase db = QSqlDatabase::database(dbName); @@ -161,7 +161,7 @@ void tst_QSql::open() QCoreApplication app(argc, argv, false); tst_Databases dbs; - dbs.open(); + QVERIFY(dbs.open()); if (count == -1) // first iteration: see how many dbs are open count = (int) dbs.dbNames.count(); @@ -188,7 +188,7 @@ void tst_QSql::concurrentAccess() QCoreApplication app(argc, argv, false); tst_Databases dbs; - dbs.open(); + QVERIFY(dbs.open()); foreach (const QString& dbName, dbs.dbNames) { QSqlDatabase db = QSqlDatabase::database(dbName); QVERIFY(db.isValid()); @@ -204,6 +204,7 @@ void tst_QSql::concurrentAccess() QVERIFY_SQL(ndb, open()); QCOMPARE(db.tables(), ndb.tables()); + ndb.close(); } // no database servers installed - don't fail QVERIFY(1); @@ -217,7 +218,7 @@ void tst_QSql::openErrorRecovery() QCoreApplication app(argc, argv, false); tst_Databases dbs; - dbs.addDbs(); + QVERIFY(dbs.addDbs()); if (dbs.dbNames.isEmpty()) QSKIP("No database drivers installed"); foreach (const QString& dbName, dbs.dbNames) { diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h index 5c8b3ef728..db01135230 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h +++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -248,7 +249,7 @@ public: dbNames.append( cName ); } - void addDbs() + bool addDbs() { //addDb("QOCI", "localhost", "system", "penandy"); // addDb( "QOCI8", "//horsehead.qt-project.org:1521/pony.troll.no", "scott", "tiger" ); // Oracle 9i on horsehead @@ -302,7 +303,10 @@ public: // use in-memory database to prevent local files // addDb("QSQLITE", ":memory:"); - addDb( "QSQLITE", QDir::toNativeSeparators(dbDir.path() + "/foo.db") ); + QTemporaryDir *sqLiteDir = dbDir(); + if (!sqLiteDir) + return false; + addDb( QStringLiteral("QSQLITE"), QDir::toNativeSeparators(sqLiteDir->path() + QStringLiteral("/foo.db")) ); // addDb( "QSQLITE2", QDir::toNativeSeparators(dbDir.path() + "/foo2.db") ); // addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.qt-project.org\\ICEBLINK", "troll", "trond", "" ); // addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.qt-project.org\\SQLEXPRESS", "troll", "trond", "" ); @@ -319,11 +323,14 @@ public: // addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2008-x86-01.qt-project.org;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" ); // addDb( "QODBC", "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\\dbs\\access\\testdb.mdb", "", "", "" ); // addDb( "QODBC", "DRIVER={Postgresql};SERVER=bq-pgsql84.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); + return true; } - void open() + // 'false' return indicates a system error, for example failure to create a temporary directory. + bool open() { - addDbs(); + if (!addDbs()) + return false; QStringList::Iterator it = dbNames.begin(); @@ -341,6 +348,7 @@ public: } } } + return true; } void close() @@ -589,7 +597,21 @@ public: QStringList dbNames; int counter; - QTemporaryDir dbDir; + +private: + QTemporaryDir *dbDir() + { + if (m_dbDir.isNull()) { + m_dbDir.reset(new QTemporaryDir); + if (!m_dbDir->isValid()) { + qWarning() << Q_FUNC_INFO << "Unable to create a temporary directory: " << QDir::toNativeSeparators(m_dbDir->path()); + m_dbDir.reset(); + } + } + return m_dbDir.data(); + } + + QScopedPointer m_dbDir; }; #endif diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index 6e199d5a71..fa5db999d4 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -394,7 +394,7 @@ void tst_QSqlDatabase::populateTestTables(QSqlDatabase db) void tst_QSqlDatabase::initTestCase() { qRegisterMetaType("QSqlDriver::NotificationSource"); - dbs.open(); + QVERIFY(dbs.open()); for (QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it) { QSqlDatabase db = QSqlDatabase::database((*it)); @@ -2229,6 +2229,7 @@ void tst_QSqlDatabase::sqlite_enable_cache_mode() QSqlQuery q(db), q2(db2); QVERIFY_SQL(q, exec("select * from " + qTableName("qtest", __FILE__, db))); QVERIFY_SQL(q2, exec("select * from " + qTableName("qtest", __FILE__, db))); + db2.close(); } QTEST_MAIN(tst_QSqlDatabase) diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp index 53e5451e06..1775aecb20 100644 --- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp +++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -69,7 +69,7 @@ private slots: void tst_QSqlDriver::initTestCase_data() { - dbs.open(); + QVERIFY(dbs.open()); if (dbs.fillTestTable() == 0) QSKIP("No database drivers are available in this Qt configuration"); } diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index a497fac79a..55cb67eed9 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -257,7 +257,7 @@ tst_QSqlQuery::~tst_QSqlQuery() void tst_QSqlQuery::initTestCase() { - dbs.open(); + QVERIFY(dbs.open()); for ( QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it ) { QSqlDatabase db = QSqlDatabase::database(( *it ) ); diff --git a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp index 1be74dc5fa..e85c64db8e 100644 --- a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp +++ b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -350,7 +350,7 @@ void tst_QSqlThread::recreateTestTables() void tst_QSqlThread::initTestCase() { - dbs.open(); + QVERIFY(dbs.open()); recreateTestTables(); } diff --git a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp index fe0f6abd9d..1e4ef73198 100644 --- a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp +++ b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -124,7 +124,7 @@ tst_QSqlQueryModel::~tst_QSqlQueryModel() void tst_QSqlQueryModel::initTestCase() { - dbs.open(); + QVERIFY(dbs.open()); for (QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it) { QSqlDatabase db = QSqlDatabase::database((*it)); CHECK_DATABASE(db); diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 37c08e5101..75a403e4b6 100644 --- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -98,7 +98,7 @@ private: void tst_QSqlRelationalTableModel::initTestCase_data() { - dbs.open(); + QVERIFY(dbs.open()); if (dbs.fillTestTable() == 0) QSKIP("No database drivers are available in this Qt configuration"); } diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index 628a34f6f4..61583f0e20 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -157,7 +157,7 @@ private: tst_QSqlTableModel::tst_QSqlTableModel() { - dbs.open(); + QVERIFY(dbs.open()); } tst_QSqlTableModel::~tst_QSqlTableModel() @@ -1968,6 +1968,7 @@ void tst_QSqlTableModel::sqlite_attachedDatabase() QCOMPARE(model.rowCount(), 1); QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toInt(), 3); QCOMPARE(model.data(model.index(0, 1), Qt::DisplayRole).toString(), QLatin1String("main")); + attachedDb.close(); } -- cgit v1.2.3 From 495c4d501e9258a0e86862fc9d4b5b4cbee14470 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Fri, 28 Mar 2014 15:41:29 +0100 Subject: Make it possible to render QtWebEngine in QOpenGLWidget Setup the GL context as shared with the Qt global share context. Change-Id: I199cfc7d290466d0ad99294bcffcd738b615862b Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index c2f7a9b184..03655639d5 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -79,6 +79,7 @@ #include "qfileinfo.h" #include #include +#include #include #include @@ -11148,6 +11149,7 @@ QOpenGLContext *QWidgetPrivate::shareContext() const QWidgetPrivate *that = const_cast(this); if (!extra->topextra->shareContext) { QOpenGLContext *ctx = new QOpenGLContext(); + ctx->setShareContext(QOpenGLContextPrivate::globalShareContext()); ctx->setFormat(extra->topextra->window->format()); ctx->create(); that->extra->topextra->shareContext = ctx; -- cgit v1.2.3 From f3eb59e3fc934f28d64f6946e86bd0a0dfbfdd4c Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 3 Apr 2014 15:17:41 +0200 Subject: Fix QTreeWidget autotest Change-Id: I94b4d9d2f0ef013691faedc4cd12050aa49e98f2 Reviewed-by: Sergio Ahumada --- tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index dfa7592813..390858ac5b 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -3092,9 +3092,14 @@ void tst_QTreeWidget::task253109_itemHeight() void tst_QTreeWidget::task206367_duplication() { QWidget topLevel; + // Explicitly set the font size because it is dpi dependent on some platforms + QFont font; + font.setPixelSize(40); + topLevel.setFont(font); QTreeWidget treeWidget(&topLevel); topLevel.show(); treeWidget.resize(200, 200); + treeWidget.setHeaderHidden(true); treeWidget.setSortingEnabled(true); QTreeWidgetItem* rootItem = new QTreeWidgetItem( &treeWidget, QStringList("root") ); @@ -3105,10 +3110,9 @@ void tst_QTreeWidget::task206367_duplication() itemFile->setExpanded(true); } rootItem->setExpanded(true); - QTest::qWait(2000); //there should be enough room for 2x2 items. If there is a scrollbar, it means the items are duplicated - QVERIFY(!treeWidget.verticalScrollBar()->isVisible()); + QTRY_VERIFY(!treeWidget.verticalScrollBar()->isVisible()); } -- cgit v1.2.3 From bf05df9a231ef1e754fe73d9c3aff6f92edbe925 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 2 Apr 2014 21:09:16 +0200 Subject: BlackBerry: Fix QListView autotest Change-Id: Id4967911d82cff86214665cc9ca3dbbefa69da11 Reviewed-by: Sergio Ahumada --- .../widgets/itemviews/qlistview/tst_qlistview.cpp | 31 +++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 9f5484983d..78a3ad021b 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -1468,15 +1468,16 @@ void tst_QListView::wordWrap() model.setStringList(list); lv.setModel(&model); lv.setWordWrap(true); - lv.setFixedSize(150, 150); -#ifdef Q_OS_BLACKBERRY - // BB standard font size is too big, triggering - // a horizontal scrollbar even when word-wrapping - // is enabled + lv.setFixedSize(400, 150); + +#if defined Q_OS_BLACKBERRY QFont font = lv.font(); - font.setPointSize(5); + // On BB10 the root window is stretched over the whole screen + // This makes sure that the text will be long enough to produce + // a vertical scrollbar + font.setPixelSize(50); lv.setFont(font); -#endif // Q_OS_BLACKBERRY +#endif lv.showNormal(); QApplication::processEvents(); @@ -2019,7 +2020,7 @@ void tst_QListView::taskQTBUG_9455_wrongScrollbarRanges() w.setViewMode(QListView::IconMode); w.resize(116, 132); w.setMovement(QListView::Static); - const int spacing = 40; + const int spacing = 200; w.setSpacing(spacing); w.showNormal(); QVERIFY(QTest::qWaitForWindowExposed(&w)); @@ -2113,6 +2114,12 @@ void tst_QListView::taskQTBUG_21115_scrollToAndHiddenItems_data() void tst_QListView::taskQTBUG_21115_scrollToAndHiddenItems() { +#if defined Q_OS_BLACKBERRY + // On BB10 we need to create a root window which is automatically stretched + // over the whole screen + QWindow rootWindow; + rootWindow.show(); +#endif QFETCH(int, flow); QListView lv; @@ -2309,6 +2316,12 @@ void tst_QListView::spacing() void tst_QListView::testScrollToWithHidden() { +#if defined Q_OS_BLACKBERRY + // On BB10 we need to create a root window which is automatically stretched + // over the whole screen + QWindow rootWindow; + rootWindow.show(); +#endif QListView lv; QStringListModel model; @@ -2321,7 +2334,7 @@ void tst_QListView::testScrollToWithHidden() lv.setRowHidden(1, true); lv.setSpacing(5); - lv.show(); + lv.showNormal(); QTest::qWaitForWindowExposed(&lv); QCOMPARE(lv.verticalScrollBar()->value(), 0); -- cgit v1.2.3 From 6d39e87f340b46637633a34fc32a72c38356473b Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Tue, 1 Apr 2014 14:29:38 +0300 Subject: [HB] Ensure we always working with non-multi font engine Change-Id: If88385d4cecdc527b7952d34e48f7ba889173c6c Reviewed-by: Lars Knoll --- src/gui/text/qfontengine.cpp | 5 +++++ src/gui/text/qharfbuzzng.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index a72ac23418..b2254c4826 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -280,6 +280,7 @@ QFixed QFontEngine::underlinePosition() const void *QFontEngine::harfbuzzFont() const { + Q_ASSERT(type() != QFontEngine::Multi); #ifdef QT_ENABLE_HARFBUZZ_NG if (useHarfbuzzNG) return hb_qt_font_get_for_engine(const_cast(this)); @@ -312,6 +313,7 @@ void *QFontEngine::harfbuzzFont() const void *QFontEngine::harfbuzzFace() const { + Q_ASSERT(type() != QFontEngine::Multi); #ifdef QT_ENABLE_HARFBUZZ_NG if (useHarfbuzzNG) return hb_qt_face_get_for_engine(const_cast(this)); @@ -329,6 +331,9 @@ void *QFontEngine::harfbuzzFace() const bool QFontEngine::supportsScript(QChar::Script script) const { + if (type() <= QFontEngine::Multi) + return true; + // ### TODO: This only works for scripts that require OpenType. More generally // for scripts that do not require OpenType we should just look at the list of // supported writing systems in the font's OS/2 table. diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp index b0bade83ee..e87747fd1b 100644 --- a/src/gui/text/qharfbuzzng.cpp +++ b/src/gui/text/qharfbuzzng.cpp @@ -605,8 +605,6 @@ _hb_qt_reference_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data) static inline hb_face_t * _hb_qt_face_create(QFontEngine *fe) { - Q_ASSERT(fe); - QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData)); Q_CHECK_PTR(data); data->user_data = fe->faceData.user_data; @@ -633,6 +631,8 @@ _hb_qt_face_release(void *user_data) hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe) { + Q_ASSERT(fe && fe->type() != QFontEngine::Multi); + if (Q_UNLIKELY(!fe->face_)) { fe->face_ = _hb_qt_face_create(fe); if (Q_UNLIKELY(!fe->face_)) @@ -647,8 +647,6 @@ hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe) static inline hb_font_t * _hb_qt_font_create(QFontEngine *fe) { - Q_ASSERT(fe); - hb_face_t *face = hb_qt_face_get_for_engine(fe); if (Q_UNLIKELY(!face)) return NULL; @@ -685,6 +683,8 @@ _hb_qt_font_release(void *user_data) hb_font_t *hb_qt_font_get_for_engine(QFontEngine *fe) { + Q_ASSERT(fe && fe->type() != QFontEngine::Multi); + if (Q_UNLIKELY(!fe->font_)) { fe->font_ = _hb_qt_font_create(fe); if (Q_UNLIKELY(!fe->font_)) -- cgit v1.2.3 From d8286729451ce18f07d47a5bc3f5af08eda860fa Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 3 Apr 2014 03:55:45 +0300 Subject: QTextEngine: Fix visual position movement for tab and object cases QTextLineItemIterator::next() was never updating itemStart and itemEnd for QScriptAnalysis::TabOrObject, thus producing incorrect insertion points for the line that contains tabs and/or objects. Change-Id: Ia964c663cc0636ba6be4500702656f989b252fba Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 3b079b7ee3..7390b566e7 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -3520,7 +3520,12 @@ QScriptItem &QTextLineItemIterator::next() if (!si->num_glyphs) eng->shape(item); + itemStart = qMax(line.from, si->position); + itemEnd = qMin(lineEnd, si->position + itemLength); + if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { + glyphsStart = 0; + glyphsEnd = 1; itemWidth = si->width; return *si; } @@ -3528,15 +3533,9 @@ QScriptItem &QTextLineItemIterator::next() unsigned short *logClusters = eng->logClusters(si); QGlyphLayout glyphs = eng->shapedGlyphs(si); - itemStart = qMax(line.from, si->position); glyphsStart = logClusters[itemStart - si->position]; - if (lineEnd < si->position + itemLength) { - itemEnd = lineEnd; - glyphsEnd = logClusters[itemEnd-si->position]; - } else { - itemEnd = si->position + itemLength; - glyphsEnd = si->num_glyphs; - } + glyphsEnd = (itemEnd == si->position + itemLength) ? si->num_glyphs : logClusters[itemEnd - si->position]; + // show soft-hyphen at line-break if (si->position + itemLength >= lineEnd && eng->layoutData->string.at(lineEnd - 1).unicode() == QChar::SoftHyphen) -- cgit v1.2.3 From 0b5911f37619acc20463f01df5588764e22a35b0 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 4 Apr 2014 07:28:20 +0300 Subject: QTextLayout: Fix visual cursor movement in some cases To guarantee proper positioning at the end of the last line in a bidirectional text we have to insert the eol position into the insertion points vector, accordingly to the visual ordering. Detection of the last *logical* item in a *visual* line is unrelaed to the text direction, it is simply `iterator.item == iterator.lastItem`. [ChangeLog][QtGui][QTextLayout] Fixed visual cursor movement in bidirectional text. Task-number: QTBUG-18060 (partially related) Change-Id: I53b6ab889ef580ab0560b620b808b1e09efc0fbd Reviewed-by: Lars Knoll Reviewed-by: Ahmed Saidi --- src/gui/text/qtextengine.cpp | 20 ++++++++------------ .../auto/widgets/widgets/qlineedit/tst_qlineedit.cpp | 13 ++++++++----- .../auto/widgets/widgets/qtextedit/tst_qtextedit.cpp | 13 ++++++++----- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 7390b566e7..a95adc75de 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -3181,23 +3181,19 @@ int QTextEngine::lineNumberForTextPosition(int pos) void QTextEngine::insertionPointsForLine(int lineNum, QVector &insertionPoints) { QTextLineItemIterator iterator(this, lineNum); - bool rtl = isRightToLeft(); bool lastLine = lineNum >= lines.size() - 1; while (!iterator.atEnd()) { - iterator.next(); - const QScriptItem *si = &layoutData->items[iterator.item]; - if (si->analysis.bidiLevel % 2) { - int i = iterator.itemEnd - 1, min = iterator.itemStart; - if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd())) - i++; - for (; i >= min; i--) + const QScriptItem &si = iterator.next(); + + int end = iterator.itemEnd; + if (lastLine && iterator.item == iterator.lastItem) + ++end; // the last item in the last line -> insert eol position + if (si.analysis.bidiLevel % 2) { + for (int i = end - 1; i >= iterator.itemStart; --i) insertionPoints.push_back(i); } else { - int i = iterator.itemStart, max = iterator.itemEnd; - if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd())) - max++; - for (; i < max; i++) + for (int i = iterator.itemStart; i < end; ++i) insertionPoints.push_back(i); } } diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 45167bac60..077e1aa1df 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -3903,7 +3903,7 @@ void tst_QLineEdit::bidiVisualMovement() do { oldPos = newPos; - QVERIFY(oldPos == positionList[i]); + QCOMPARE(oldPos, positionList[i]); if (basicDir == QChar::DirL) { QTest::keyClick(&le, Qt::Key_Right); } else @@ -3913,12 +3913,12 @@ void tst_QLineEdit::bidiVisualMovement() i++; } while (moved); - QVERIFY(i == positionList.size()); + QCOMPARE(i, positionList.size()); do { i--; oldPos = newPos; - QVERIFY(oldPos == positionList[i]); + QCOMPARE(oldPos, positionList[i]); if (basicDir == QChar::DirL) { QTest::keyClick(&le, Qt::Key_Left); } else @@ -3939,6 +3939,7 @@ void tst_QLineEdit::bidiLogicalMovement() { QFETCH(QString, logical); QFETCH(int, basicDir); + QFETCH(IntList, positionList); QLineEdit le; le.setText(logical); @@ -3951,7 +3952,7 @@ void tst_QLineEdit::bidiLogicalMovement() do { oldPos = newPos; - QVERIFY(oldPos == i); + QCOMPARE(oldPos, i); if (basicDir == QChar::DirL) { QTest::keyClick(&le, Qt::Key_Right); } else @@ -3961,10 +3962,12 @@ void tst_QLineEdit::bidiLogicalMovement() i++; } while (moved); + QCOMPARE(i, positionList.size()); + do { i--; oldPos = newPos; - QVERIFY(oldPos == i); + QCOMPARE(oldPos, i); if (basicDir == QChar::DirL) { QTest::keyClick(&le, Qt::Key_Left); } else diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 8695c8b29a..fbd8b46466 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -2304,7 +2304,7 @@ void tst_QTextEdit::bidiVisualMovement() do { oldPos = newPos; - QVERIFY(oldPos == positionList[i]); + QCOMPARE(oldPos, positionList[i]); if (basicDir == QChar::DirL) { ed->moveCursor(QTextCursor::Right); } else @@ -2316,12 +2316,12 @@ void tst_QTextEdit::bidiVisualMovement() i++; } while (moved); - QVERIFY(i == positionList.size()); + QCOMPARE(i, positionList.size()); do { i--; oldPos = newPos; - QVERIFY(oldPos == positionList[i]); + QCOMPARE(oldPos, positionList[i]); if (basicDir == QChar::DirL) { ed->moveCursor(QTextCursor::Left); } else @@ -2342,6 +2342,7 @@ void tst_QTextEdit::bidiLogicalMovement() { QFETCH(QString, logical); QFETCH(int, basicDir); + QFETCH(QList, positionList); ed->setText(logical); @@ -2358,7 +2359,7 @@ void tst_QTextEdit::bidiLogicalMovement() do { oldPos = newPos; - QVERIFY(oldPos == i); + QCOMPARE(oldPos, i); if (basicDir == QChar::DirL) { ed->moveCursor(QTextCursor::Right); } else @@ -2370,10 +2371,12 @@ void tst_QTextEdit::bidiLogicalMovement() i++; } while (moved); + QCOMPARE(i, positionList.size()); + do { i--; oldPos = newPos; - QVERIFY(oldPos == i); + QCOMPARE(oldPos, i); if (basicDir == QChar::DirL) { ed->moveCursor(QTextCursor::Left); } else -- cgit v1.2.3 From 47056e78d3d963272e449e8f917ae3208b7aa940 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 4 Apr 2014 07:30:20 +0300 Subject: Optimize QTextEngine::insertionPointsForLine() a bit Reserve the insertionPoints vector capacity prior to multiple append()-s. Change-Id: I97ab5b2a1add9f2e87c04ad0707bf516c13ff4d7 Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index a95adc75de..53fd37abba 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -3181,6 +3181,9 @@ int QTextEngine::lineNumberForTextPosition(int pos) void QTextEngine::insertionPointsForLine(int lineNum, QVector &insertionPoints) { QTextLineItemIterator iterator(this, lineNum); + + insertionPoints.reserve(iterator.line.length); + bool lastLine = lineNum >= lines.size() - 1; while (!iterator.atEnd()) { -- cgit v1.2.3 From 330f6e359897f77cf50f67141d09e94c371121ff Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 4 Apr 2014 07:31:24 +0300 Subject: QTextLayout: Fix cursor movement from invalid position Actually guarantee cursor doesn't move in this case for both logical and visual modes (just what the documentation says we already do ;) Change-Id: Iabdca7aa1d205672386a0095e3487e585611cdb5 Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 15 ++++++---- src/gui/text/qtextlayout.cpp | 5 +++- tests/auto/other/qcomplextext/tst_qcomplextext.cpp | 33 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 53fd37abba..35950c709b 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -3138,11 +3138,12 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end, int QTextEngine::previousLogicalPosition(int oldPos) const { const QCharAttributes *attrs = attributes(); - if (!attrs || oldPos < 0) + int len = block.isValid() ? block.length() - 1 + : layoutData->string.length(); + Q_ASSERT(len <= layoutData->string.length()); + if (!attrs || oldPos <= 0 || oldPos > len) return oldPos; - if (oldPos <= 0) - return 0; oldPos--; while (oldPos && !attrs[oldPos].graphemeBoundary) oldPos--; @@ -3224,8 +3225,7 @@ int QTextEngine::beginningOfLine(int lineNum) int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op) { - if (!layoutData) - itemize(); + itemize(); bool moveRight = (op == QTextCursor::Right); bool alignRight = isRightToLeft(); @@ -3233,7 +3233,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos); int lineNum = lineNumberForTextPosition(pos); - Q_ASSERT(lineNum >= 0); + if (lineNum < 0) + return pos; QVector insertionPoints; insertionPointsForLine(lineNum, insertionPoints); @@ -3256,6 +3257,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation if (lineNum > 0) return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1); } + + break; } return pos; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 0c9866c6cf..c3cf2e56bb 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -674,7 +674,10 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const { const QCharAttributes *attributes = d->attributes(); - if (!attributes || oldPos <= 0 || oldPos > d->layoutData->string.length()) + int len = d->block.isValid() ? d->block.length() - 1 + : d->layoutData->string.length(); + Q_ASSERT(len <= d->layoutData->string.length()); + if (!attributes || oldPos <= 0 || oldPos > len) return oldPos; if (mode == SkipCharacters) { diff --git a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp index 7eb8479372..cc444872ec 100644 --- a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp @@ -71,6 +71,8 @@ private slots: void bidiCursorMovement(); void bidiCursorLogicalMovement_data(); void bidiCursorLogicalMovement(); + void bidiInvalidCursorNoMovement_data(); + void bidiInvalidCursorNoMovement(); }; tst_QComplexText::tst_QComplexText() @@ -272,6 +274,37 @@ void tst_QComplexText::bidiCursorLogicalMovement() } while (moved); } +void tst_QComplexText::bidiInvalidCursorNoMovement_data() +{ + bidiCursorMovement_data(); +} + +void tst_QComplexText::bidiInvalidCursorNoMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QTextLayout layout(logical); + + QTextOption option = layout.textOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + layout.setTextOption(option); + + // visual + QCOMPARE(layout.rightCursorPosition(-1000), -1000); + QCOMPARE(layout.rightCursorPosition(1000), 1000); + + QCOMPARE(layout.leftCursorPosition(-1000), -1000); + QCOMPARE(layout.leftCursorPosition(1000), 1000); + + // logical + QCOMPARE(layout.nextCursorPosition(-1000), -1000); + QCOMPARE(layout.nextCursorPosition(1000), 1000); + + QCOMPARE(layout.previousCursorPosition(-1000), -1000); + QCOMPARE(layout.previousCursorPosition(1000), 1000); +} + void tst_QComplexText::bidiCursor_PDF() { QString str = QString::fromUtf8("\342\200\252hello\342\200\254"); -- cgit v1.2.3 From c603a295501cfa99f1592e120ab40ba0db759a81 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 4 Apr 2014 13:55:32 +0300 Subject: Remove spurious #ifdef from tst_QComplexText That #ifdef is placed before any include, so it has no effect. Change-Id: I4bbf967bda720d287b363847669c5c7a22807bc4 Reviewed-by: Eskil Abrahamsen Blomfeldt --- tests/auto/other/qcomplextext/tst_qcomplextext.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp index cc444872ec..03c51d9d6e 100644 --- a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp @@ -39,11 +39,6 @@ ** ****************************************************************************/ - -// Horrible hack, but this get this out of the way for now -// Carlos Duclos, 2007-12-11 -#if !defined(Q_OS_MAC) - #include #include #include @@ -322,6 +317,3 @@ void tst_QComplexText::bidiCursor_PDF() QTEST_MAIN(tst_QComplexText) #include "tst_qcomplextext.moc" - -#endif // Q_OS_MAC - -- cgit v1.2.3 From 8c0919a2863948ed8705893c574b481dcdc30ff2 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 4 Apr 2014 07:23:59 +0300 Subject: Remove QtWidgets dependency from tst_QComplexText It doesn't depends on windget for quite a long time already. Change-Id: I251e2e0d52028d17a61c892308d099f344728e79 Reviewed-by: Lars Knoll --- tests/auto/other/other.pro | 1 - tests/auto/other/qcomplextext/qcomplextext.pro | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index 2bddc8d127..f7f22fd71e 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -33,7 +33,6 @@ SUBDIRS=\ languagechange \ modeltest \ qaccessibility \ - qcomplextext \ qfocusevent \ qnetworkaccessmanager_and_qprogressdialog \ qsharedpointer_and_qwidget \ diff --git a/tests/auto/other/qcomplextext/qcomplextext.pro b/tests/auto/other/qcomplextext/qcomplextext.pro index 7848028134..28acc397bf 100644 --- a/tests/auto/other/qcomplextext/qcomplextext.pro +++ b/tests/auto/other/qcomplextext/qcomplextext.pro @@ -1,7 +1,7 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qcomplextext -QT += widgets widgets-private testlib +QT += testlib QT += core-private gui-private SOURCES += tst_qcomplextext.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 -- cgit v1.2.3 From 964ac38fb0dc84e05606b3abf6f7fcb887a62528 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 18 Mar 2014 16:43:36 -0700 Subject: Don't read before the beginning of the string The code did discard the the data, so it wasn't affecting the comparison result (tests added anyway), but it could cause crashes if the pointer to the beginning of the data in the first 8 bytes of a page. Change-Id: I618e68de329b65de34ef8c934934c3e631cc6c9f Reported-By: Erik Verbruggen Reviewed-by: Erik Verbruggen --- src/corelib/tools/qstring.cpp | 16 +++++--- .../corelib/tools/qstringref/tst_qstringref.cpp | 48 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 7d409708bb..79365b11b1 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -559,11 +559,13 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) } } - // we'll read uc[offset..offset+7] (16 bytes) and c[offset-8..offset+7] (16 bytes) +# ifdef Q_PROCESSOR_X86_64 + enum { MaxTailLength = 7 }; + // we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes) if (uc + offset + 7 < e) { - // same, but we'll throw away half the data - __m128i chunk = _mm_loadu_si128((__m128i*)(c + offset - 8)); - __m128i secondHalf = _mm_unpackhi_epi8(chunk, nullmask); + // same, but we're using an 8-byte load + __m128i chunk = _mm_cvtsi64_si128(*(long long *)(c + offset)); + __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask); __m128i ucdata = _mm_loadu_si128((__m128i*)(uc + offset)); __m128i result = _mm_cmpeq_epi16(secondHalf, ucdata); @@ -577,6 +579,10 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) // still matched offset += 8; } +# else + // 32-bit, we can't do MOVQ to load 8 bytes + enum { MaxTailLength = 15 }; +# endif // reset uc and c uc += offset; @@ -584,7 +590,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) # ifdef Q_COMPILER_LAMBDA const auto &lambda = [=](int i) { return uc[i] - ushort(c[i]); }; - return UnrollTailLoop<7>::exec(e - uc, 0, lambda, lambda); + return UnrollTailLoop::exec(e - uc, 0, lambda, lambda); # endif #endif diff --git a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp index 7bbcee8ab2..342abb7ea8 100644 --- a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp +++ b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp @@ -68,6 +68,8 @@ private slots: void isEmpty(); void compare_data(); void compare(); + void compare2_data(); + void compare2(); void operator_eqeq_nullstring(); void toNum(); void toDouble_data(); @@ -792,11 +794,17 @@ void tst_QStringRef::compare_data() QTest::newRow("data3") << QString("abc") << QString("abc") << 0 << 0; QTest::newRow("data4") << QString("abC") << QString("abc") << -1 << 0; QTest::newRow("data5") << QString("abc") << QString("abC") << 1 << 0; + QTest::newRow("data10") << QString("abcdefgh") << QString("abcdefgh") << 0 << 0; + QTest::newRow("data11") << QString("abcdefgh") << QString("abCdefgh") << 1 << 0; + QTest::newRow("data12") << QString("0123456789012345") << QString("0123456789012345") << 0 << 0; + QTest::newRow("data13") << QString("0123556789012345") << QString("0123456789012345") << 1 << 1; // different length QTest::newRow("data6") << QString("abcdef") << QString("abc") << 1 << 1; QTest::newRow("data7") << QString("abCdef") << QString("abc") << -1 << 1; QTest::newRow("data8") << QString("abc") << QString("abcdef") << -1 << -1; + QTest::newRow("data14") << QString("abcdefgh") << QString("abcdefghi") << -1 << -1; + QTest::newRow("data15") << QString("01234567890123456") << QString("0123456789012345") << 1 << 1; QString upper; upper += QChar(QChar::highSurrogate(0x10400)); @@ -862,6 +870,46 @@ void tst_QStringRef::compare() } } +void tst_QStringRef::compare2_data() +{ + compare_data(); +} + +void tst_QStringRef::compare2() +{ + QFETCH(QString, s1); + QFETCH(QString, s2); + QFETCH(int, csr); + QFETCH(int, cir); + + // prepend and append data + // we only use Latin1 here so isLatin1 still results true + s1.prepend("xyz").append("zyx"); + s2.prepend("foobar").append("raboof"); + + QStringRef r1(&s1, 3, s1.length() - 6); + QStringRef r2(&s2, 6, s2.length() - 12); + + QCOMPARE(sign(QStringRef::compare(r1, r2)), csr); + QCOMPARE(sign(r1.compare(r2)), csr); + + QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir); + + QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir); + + if (isLatin(s2)) { + QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(r2.toLatin1()))), csr); + QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(r2.toLatin1()), Qt::CaseInsensitive)), cir); + } + + if (isLatin(s1)) { + QCOMPARE(sign(QStringRef::compare(r2, QLatin1String(r1.toLatin1()))), -csr); + QCOMPARE(sign(QStringRef::compare(r2, QLatin1String(r1.toLatin1()), Qt::CaseInsensitive)), -cir); + } +} + void tst_QStringRef::toNum() { #define TEST_TO_INT(num, func, type) \ -- cgit v1.2.3 From 7d4bc536a27be540516a0403e114668f9eee65bb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 2 Apr 2014 18:25:52 -0700 Subject: Don't fileFixify PRECOMPILED_HEADER twice fileFixify must not be called twice on the same file path, since it will convert an absolute path from the shadow build to an absolute path in the source dir. The first fileFixify occurs in MakefileGenerator::init, along with the fixifying of INCLUDEPATH. Change-Id: I607870573a80eaf834ea5f540bbe1451ec983114 Reviewed-by: Oswald Buddenhagen --- qmake/generators/unix/unixmake.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index cadd5cf316..c11259d5a1 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -210,7 +210,7 @@ UnixMakefileGenerator::init() // replace place holders pchFlags = pchFlags.replace("${QMAKE_PCH_INPUT}", - fileFixify(project->first("PRECOMPILED_HEADER").toQString())); + project->first("PRECOMPILED_HEADER").toQString()); pchFlags = pchFlags.replace("${QMAKE_PCH_OUTPUT_BASE}", pchBaseName); if (project->isActiveConfig("icc_pch_style")) { // icc style -- cgit v1.2.3 From a4ec90175c76ce35688acc06cdf93e9cab886223 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 3 Mar 2014 21:20:30 +0100 Subject: purge vestiges of opengl es 1 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amends 0d5170256c1. Change-Id: Ifa178d38f602bb7c66ef13334673ff47e332af5b Reviewed-by: Jørgen Lind Reviewed-by: Laszlo Agocs --- config.tests/unix/egl4gles1/egl4gles1.cpp | 51 ---- config.tests/unix/egl4gles1/egl4gles1.pro | 10 - config.tests/unix/opengles1/opengles1.cpp | 55 ---- config.tests/unix/opengles1/opengles1.pro | 12 - examples/gui/gui.pro | 2 +- examples/opengl/hellogl_es/glwindow.cpp | 320 ------------------------ examples/opengl/hellogl_es/glwindow.h | 78 ------ examples/opengl/hellogl_es/hellogl_es.pro | 11 - examples/opengl/hellogl_es/main.cpp | 52 ---- examples/opengl/hellogl_es/qt.png | Bin 5174 -> 0 bytes examples/opengl/hellogl_es/texture.qrc | 5 - examples/opengl/opengl.pro | 18 +- examples/widgets/painting/shared/shared.pri | 2 +- examples/widgets/widgets.pro | 4 +- mkspecs/android-g++/qmake.conf | 1 - mkspecs/common/ios/qmake.conf | 5 - mkspecs/common/linux-android.conf | 3 - mkspecs/common/linux.conf | 3 - mkspecs/common/qcc-base-qnx.conf | 1 - mkspecs/common/wince/qmake.conf | 1 - mkspecs/features/egl.prf | 29 +-- mkspecs/features/opengles1.prf | 2 - mkspecs/features/unix/opengl.prf | 7 +- mkspecs/hurd-g++/qmake.conf | 3 - mkspecs/unsupported/android-g++/qmake.conf | 3 - mkspecs/unsupported/linux-host-g++/qmake.conf | 3 - qmake/doc/src/qmake-manual.qdoc | 7 +- src/gui/gui.pro | 9 +- src/gui/kernel/qopenglcontext.cpp | 3 - src/gui/kernel/qopenglcontext.h | 3 +- src/gui/opengl/qopenglbuffer.cpp | 16 +- src/gui/opengl/qopenglfunctions.cpp | 22 +- src/opengl/opengl.pro | 1 - src/opengl/qglbuffer.cpp | 16 +- src/opengl/qglfunctions.cpp | 22 +- src/openglextensions/openglextensions.pro | 1 - src/src.pro | 4 +- tests/auto/cmake/test_opengl_lib/CMakeLists.txt | 4 +- tests/auto/cmake/test_opengl_lib/main.cpp | 4 +- tests/auto/gui/gui.pro | 2 +- tools/configure/configureapp.cpp | 20 +- 41 files changed, 45 insertions(+), 770 deletions(-) delete mode 100644 config.tests/unix/egl4gles1/egl4gles1.cpp delete mode 100644 config.tests/unix/egl4gles1/egl4gles1.pro delete mode 100644 config.tests/unix/opengles1/opengles1.cpp delete mode 100644 config.tests/unix/opengles1/opengles1.pro delete mode 100644 examples/opengl/hellogl_es/glwindow.cpp delete mode 100644 examples/opengl/hellogl_es/glwindow.h delete mode 100644 examples/opengl/hellogl_es/hellogl_es.pro delete mode 100644 examples/opengl/hellogl_es/main.cpp delete mode 100644 examples/opengl/hellogl_es/qt.png delete mode 100644 examples/opengl/hellogl_es/texture.qrc delete mode 100644 mkspecs/features/opengles1.prf diff --git a/config.tests/unix/egl4gles1/egl4gles1.cpp b/config.tests/unix/egl4gles1/egl4gles1.cpp deleted file mode 100644 index 829ceafeb8..0000000000 --- a/config.tests/unix/egl4gles1/egl4gles1.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - EGLint x = 0; - EGLDisplay dpy = 0; - EGLContext ctx = 0; - eglDestroyContext(dpy, ctx); - return 0; -} diff --git a/config.tests/unix/egl4gles1/egl4gles1.pro b/config.tests/unix/egl4gles1/egl4gles1.pro deleted file mode 100644 index 667ea8e3ac..0000000000 --- a/config.tests/unix/egl4gles1/egl4gles1.pro +++ /dev/null @@ -1,10 +0,0 @@ -SOURCES = egl4gles1.cpp - -for(p, QMAKE_LIBDIR_EGL) { - exists($$p):LIBS += -L$$p -} - -!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL -!isEmpty(QMAKE_LIBS_EGL): LIBS += $$QMAKE_LIBS_EGL - -CONFIG -= qt diff --git a/config.tests/unix/opengles1/opengles1.cpp b/config.tests/unix/opengles1/opengles1.cpp deleted file mode 100644 index 690974138a..0000000000 --- a/config.tests/unix/opengles1/opengles1.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifdef BUILD_ON_MAC - #include -#else - #include -#endif - -int main(int, char **) -{ - GLfloat a = 1.0f; - glColor4f(a, a, a, a); - glClear(GL_COLOR_BUFFER_BIT); - - return 0; -} diff --git a/config.tests/unix/opengles1/opengles1.pro b/config.tests/unix/opengles1/opengles1.pro deleted file mode 100644 index 58817e6a6e..0000000000 --- a/config.tests/unix/opengles1/opengles1.pro +++ /dev/null @@ -1,12 +0,0 @@ -SOURCES = opengles1.cpp -INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1 - -for(p, QMAKE_LIBDIR_OPENGL_ES1) { - exists($$p):LIBS += -L$$p -} - -CONFIG -= qt -LIBS += $$QMAKE_LIBS_OPENGL_ES1 -mac { - DEFINES += BUILD_ON_MAC -} diff --git a/examples/gui/gui.pro b/examples/gui/gui.pro index 5fb4241e74..3a63ffb5eb 100644 --- a/examples/gui/gui.pro +++ b/examples/gui/gui.pro @@ -5,6 +5,6 @@ CONFIG += no_docs_target SUBDIRS += analogclock SUBDIRS += rasterwindow -contains(QT_CONFIG, opengl(es1|es2)?) { +contains(QT_CONFIG, opengl(es2)?) { SUBDIRS += openglwindow } diff --git a/examples/opengl/hellogl_es/glwindow.cpp b/examples/opengl/hellogl_es/glwindow.cpp deleted file mode 100644 index 38366ee785..0000000000 --- a/examples/opengl/hellogl_es/glwindow.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "glwindow.h" - -#include -#include -#include - -#include -#include - -inline void CrossProduct(qreal &xOut, qreal &yOut, qreal &zOut, qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2) -{ - xOut = y1 * z2 - z1 * y2; - yOut = z1 * x2 - x1 * z2; - zOut = x1 * y2 - y1 * x2; -} - -inline void Normalize(qreal &x, qreal &y, qreal &z) -{ - qreal l = sqrt(x*x + y*y + z*z); - x = x / l; - y = y / l; - z = z / l; -} - -GLWindow::GLWindow() -{ - setSurfaceType(OpenGLSurface); - - qtLogo = true; - createdVertices = 0; - createdNormals = 0; - m_vertexNumber = 0; - frames = 0; - - m_fScale = 1; - - QSurfaceFormat format; - format.setDepthBufferSize(24); - format.setMajorVersion(1); - format.setMinorVersion(1); - - setGeometry(QGuiApplication::primaryScreen()->availableGeometry()); - setFormat(format); - create(); - - m_context = new QOpenGLContext; - m_context->setFormat(format); - m_context->create(); - - m_context->makeCurrent(this); - initializeGL(); - - QTimer *timer = new QTimer(this); - timer->setInterval(16); - connect(timer, SIGNAL(timeout()), this, SLOT(paintGL())); - timer->start(); -} - -GLWindow::~GLWindow() -{ - if (createdVertices) - delete[] createdVertices; - if (createdNormals) - delete[] createdNormals; - - delete m_context; -} - -void GLWindow::paintQtLogo() -{ - glDisable(GL_TEXTURE_2D); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3,GL_FLOAT,0, createdVertices); - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT,0,createdNormals); - glDrawArrays(GL_TRIANGLES, 0, m_vertexNumber / 3); -} - -void GLWindow::initializeGL () -{ - glClearColor(0.1f, 0.1f, 0.2f, 1.0f); - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - - GLfloat aLightPosition[] = {0.0f,0.3f,1.0f,0.0f}; - - glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, aLightPosition); - m_fAngle = 0; - m_fScale = 1; - createGeometry(); -} - -void GLWindow::paintGL() -{ - m_context->makeCurrent(this); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - - //Since OpenGL ES does not support glPush/PopAttrib(GL_ALL_ATTRIB_BITS) - //we have to take care of the states ourselves - - glClearColor(0.1f, 0.1f, 0.2f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_TEXTURE_2D); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - - glShadeModel(GL_FLAT); - glFrontFace(GL_CW); - glCullFace(GL_FRONT); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glRotatef(m_fAngle, 0.0f, 1.0f, 0.0f); - glRotatef(m_fAngle, 1.0f, 0.0f, 0.0f); - glRotatef(m_fAngle, 0.0f, 0.0f, 1.0f); - glScalef(m_fScale, m_fScale,m_fScale); - glTranslatef(0.0f,-0.2f,0.0f); - - GLfloat matDiff[] = {0.40f, 1.0f, 0.0f, 1.0f}; - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff); - - paintQtLogo(); - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_TEXTURE); - glPopMatrix(); - - glDisable(GL_LIGHTING); - glDisable(GL_LIGHT0); - - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - - m_context->swapBuffers(this); - - m_fAngle += 1.0f; -} - -void GLWindow::createGeometry() -{ - vertices.clear(); - normals.clear(); - - qreal x1 = +0.06f; - qreal y1 = -0.14f; - qreal x2 = +0.14f; - qreal y2 = -0.06f; - qreal x3 = +0.08f; - qreal y3 = +0.00f; - qreal x4 = +0.30f; - qreal y4 = +0.22f; - - quad(x1, y1, x2, y2, y2, x2, y1, x1); - quad(x3, y3, x4, y4, y4, x4, y3, x3); - - extrude(x1, y1, x2, y2); - extrude(x2, y2, y2, x2); - extrude(y2, x2, y1, x1); - extrude(y1, x1, x1, y1); - extrude(x3, y3, x4, y4); - extrude(x4, y4, y4, x4); - extrude(y4, x4, y3, x3); - - const qreal Pi = 3.14159f; - const int NumSectors = 100; - - for (int i = 0; i < NumSectors; ++i) { - qreal angle1 = (i * 2 * Pi) / NumSectors; - qreal x5 = 0.30 * sin(angle1); - qreal y5 = 0.30 * cos(angle1); - qreal x6 = 0.20 * sin(angle1); - qreal y6 = 0.20 * cos(angle1); - - qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors; - qreal x7 = 0.20 * sin(angle2); - qreal y7 = 0.20 * cos(angle2); - qreal x8 = 0.30 * sin(angle2); - qreal y8 = 0.30 * cos(angle2); - - quad(x5, y5, x6, y6, x7, y7, x8, y8); - - extrude(x6, y6, x7, y7); - extrude(x8, y8, x5, y5); - } - - m_vertexNumber = vertices.size(); - createdVertices = new GLfloat[m_vertexNumber]; - createdNormals = new GLfloat[m_vertexNumber]; - for (int i = 0;i < m_vertexNumber;i++) { - createdVertices[i] = vertices.at(i) * 2; - createdNormals[i] = normals.at(i); - } - vertices.clear(); - normals.clear(); -} - -void GLWindow::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4) -{ - qreal nx, ny, nz; - - vertices << x1 << y1 << -0.05f; - vertices << x2 << y2 << -0.05f; - vertices << x4 << y4 << -0.05f; - - vertices << x3 << y3 << -0.05f; - vertices << x4 << y4 << -0.05f; - vertices << x2 << y2 << -0.05f; - - CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0, x4 - x1, y4 - y1, 0); - Normalize(nx, ny, nz); - - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; - - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; - - vertices << x4 << y4 << 0.05f; - vertices << x2 << y2 << 0.05f; - vertices << x1 << y1 << 0.05f; - - vertices << x2 << y2 << 0.05f; - vertices << x4 << y4 << 0.05f; - vertices << x3 << y3 << 0.05f; - - CrossProduct(nx, ny, nz, x2 - x4, y2 - y4, 0, x1 - x4, y1 - y4, 0); - Normalize(nx, ny, nz); - - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; - - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; -} - -void GLWindow::extrude(qreal x1, qreal y1, qreal x2, qreal y2) -{ - qreal nx, ny, nz; - - vertices << x1 << y1 << +0.05f; - vertices << x2 << y2 << +0.05f; - vertices << x1 << y1 << -0.05f; - - vertices << x2 << y2 << -0.05f; - vertices << x1 << y1 << -0.05f; - vertices << x2 << y2 << +0.05f; - - CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0.0f, 0.0f, 0.0f, -0.1f); - Normalize(nx, ny, nz); - - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; - - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; -} diff --git a/examples/opengl/hellogl_es/glwindow.h b/examples/opengl/hellogl_es/glwindow.h deleted file mode 100644 index 752145fff9..0000000000 --- a/examples/opengl/hellogl_es/glwindow.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GLWINDOW_H -#define GLWINDOW_H - -#include - -#include -#include -#include - -class GLWindow : public QWindow { - Q_OBJECT -public: - GLWindow(); - ~GLWindow(); - -protected slots: - void paintGL(); - void initializeGL(); - -private: - qreal m_fAngle; - qreal m_fScale; - QOpenGLContext *m_context; - void paintQtLogo(); - void createGeometry(); - void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4); - void extrude(qreal x1, qreal y1, qreal x2, qreal y2); - QList vertices; - QList normals; - GLfloat *createdVertices; - GLfloat *createdNormals; - int m_vertexNumber; - bool qtLogo; - int frames; - QTime time; -}; - -#endif diff --git a/examples/opengl/hellogl_es/hellogl_es.pro b/examples/opengl/hellogl_es/hellogl_es.pro deleted file mode 100644 index 56328030d5..0000000000 --- a/examples/opengl/hellogl_es/hellogl_es.pro +++ /dev/null @@ -1,11 +0,0 @@ -QT += gui - -SOURCES += main.cpp -SOURCES += glwindow.cpp - -HEADERS += glwindow.h - -RESOURCES += texture.qrc - -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellogl_es -INSTALLS += target diff --git a/examples/opengl/hellogl_es/main.cpp b/examples/opengl/hellogl_es/main.cpp deleted file mode 100644 index 6cb5647024..0000000000 --- a/examples/opengl/hellogl_es/main.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "glwindow.h" - -int main( int argc, char ** argv ) -{ - Q_INIT_RESOURCE(texture); - QGuiApplication a( argc, argv ); - GLWindow window; - window.show(); - return a.exec(); -} diff --git a/examples/opengl/hellogl_es/qt.png b/examples/opengl/hellogl_es/qt.png deleted file mode 100644 index 79e383cf50..0000000000 Binary files a/examples/opengl/hellogl_es/qt.png and /dev/null differ diff --git a/examples/opengl/hellogl_es/texture.qrc b/examples/opengl/hellogl_es/texture.qrc deleted file mode 100644 index ff1d0e535f..0000000000 --- a/examples/opengl/hellogl_es/texture.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - qt.png - - diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index bcf62b6551..7bc96234df 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -2,16 +2,8 @@ requires(qtHaveModule(opengl)) TEMPLATE = subdirs -contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2){ - contains(QT_CONFIG, opengles2) { - SUBDIRS = hellogl_es2 - } else { - SUBDIRS = hellogl_es - } - SUBDIRS += textures - contains(QT_CONFIG, opengles1) { - SUBDIRS += hellogl - } +contains(QT_CONFIG, opengles2) { + SUBDIRS = hellogl_es2 } else { SUBDIRS = 2dpainting \ grabber \ @@ -19,13 +11,13 @@ contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2){ overpainting \ pbuffers \ framebufferobject2 \ - samplebuffers \ - textures + samplebuffers } SUBDIRS += hellowindow \ paintedwindow \ contextinfo \ - cube + cube \ + textures EXAMPLE_FILES = shared diff --git a/examples/widgets/painting/shared/shared.pri b/examples/widgets/painting/shared/shared.pri index af027e081a..c8d119f4e5 100644 --- a/examples/widgets/painting/shared/shared.pri +++ b/examples/widgets/painting/shared/shared.pri @@ -1,6 +1,6 @@ INCLUDEPATH += $$PWD -qtHaveModule(opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) { +qtHaveModule(opengl)|contains(QT_CONFIG, opengles2) { DEFINES += QT_OPENGL_SUPPORT QT += opengl widgets } diff --git a/examples/widgets/widgets.pro b/examples/widgets/widgets.pro index d7d3dbc445..cc489b5c16 100644 --- a/examples/widgets/widgets.pro +++ b/examples/widgets/widgets.pro @@ -22,11 +22,11 @@ SUBDIRS = \ tutorials \ widgets -contains(QT_CONFIG, opengl(es1|es2)?) { +contains(QT_CONFIG, opengl(es2)?) { SUBDIRS += windowcontainer } -!contains(QT_CONFIG, opengl(es1|es2)?): SUBDIRS -= windowcontainer +!contains(QT_CONFIG, opengl(es2)?): SUBDIRS -= windowcontainer contains(DEFINES, QT_NO_CURSOR): SUBDIRS -= mainwindows contains(DEFINES, QT_NO_DRAGANDDROP): SUBDIRS -= draganddrop mac:SUBDIRS += mac diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index 732d415f9a..44624fcca5 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -186,7 +186,6 @@ QMAKE_LIBS_X11 = QMAKE_LIBS_THREAD = QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_OPENGL = -QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 !exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.") diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index 3c477438a3..daf66ac5ea 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -15,11 +15,6 @@ QMAKE_RANLIB = ranlib -s QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX -# No OpenGL ES1 -QMAKE_INCDIR_OPENGL_ES1 = -QMAKE_LIBDIR_OPENGL_ES1 = -QMAKE_LIBS_OPENGL_ES1 = - # OpenGL ES2 QMAKE_INCDIR_OPENGL_ES2 = QMAKE_LIBDIR_OPENGL_ES2 = diff --git a/mkspecs/common/linux-android.conf b/mkspecs/common/linux-android.conf index b90a22ebef..fec008cb45 100644 --- a/mkspecs/common/linux-android.conf +++ b/mkspecs/common/linux-android.conf @@ -74,8 +74,6 @@ QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$ANDROID_PLATFORM_PA QMAKE_INCDIR_X11 = QMAKE_LIBDIR_X11 = QMAKE_INCDIR_OPENGL = -QMAKE_INCDIR_OPENGL_ES1 = -QMAKE_LIBDIR_OPENGL_ES1 = QMAKE_INCDIR_OPENGL_ES2 = QMAKE_LIBDIR_OPENGL_ES2 = @@ -110,7 +108,6 @@ QMAKE_LIBS_QT_OPENGL = QMAKE_LIBS_QTOPIA = QMAKE_LIBS_THREAD = QMAKE_LIBS_OPENGL = -QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $$QMAKE_LIBS load(qt_config) diff --git a/mkspecs/common/linux.conf b/mkspecs/common/linux.conf index c727bd9aef..98e6cefabd 100644 --- a/mkspecs/common/linux.conf +++ b/mkspecs/common/linux.conf @@ -13,8 +13,6 @@ QMAKE_INCDIR_X11 = QMAKE_LIBDIR_X11 = QMAKE_INCDIR_OPENGL = QMAKE_LIBDIR_OPENGL = -QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL -QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_EGL = @@ -28,7 +26,6 @@ QMAKE_LIBS_X11 = -lXext -lX11 -lm QMAKE_LIBS_NIS = -lnsl QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_OPENGL = -lGL -QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 QMAKE_LIBS_OPENVG = -lOpenVG QMAKE_LIBS_THREAD = -lpthread diff --git a/mkspecs/common/qcc-base-qnx.conf b/mkspecs/common/qcc-base-qnx.conf index e08ac9621e..0954cfd1ee 100644 --- a/mkspecs/common/qcc-base-qnx.conf +++ b/mkspecs/common/qcc-base-qnx.conf @@ -29,7 +29,6 @@ QMAKE_LIBS = -lm QMAKE_LIBS_NETWORK = -lsocket # OpenGL libraries have a dependency on libEGL -QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM -lEGL QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 -lEGL QMAKE_LIBS_EGL = -lEGL diff --git a/mkspecs/common/wince/qmake.conf b/mkspecs/common/wince/qmake.conf index 5e6e6f0421..6e2e24dbd0 100644 --- a/mkspecs/common/wince/qmake.conf +++ b/mkspecs/common/wince/qmake.conf @@ -65,7 +65,6 @@ QMAKE_LIBS_COMPAT = QMAKE_EXTENSION_STATICLIB = lib QMAKE_LIBS_EGL = libEGL.lib -QMAKE_LIBS_OPENGL_ES1 = libGLES_CM.lib QMAKE_LIBS_OPENGL_ES2 = libGLESv2.lib QMAKE_LIBS_QT_ENTRY = -lqtmain diff --git a/mkspecs/features/egl.prf b/mkspecs/features/egl.prf index 3dd66bce53..c3bdd9fdf4 100644 --- a/mkspecs/features/egl.prf +++ b/mkspecs/features/egl.prf @@ -1,23 +1,8 @@ -# On UNIX, we can use config tests to figure out if egl.h is in -# EGL/egl.h or GLES/egl.h. Sadly, there are no config tests on WinCE -# so we have to assume that for GLES 1.1 (CL), the EGL header is in -# GLES/egl.h. We also assume there is no separate libEGL.lib library, -# so we use the GL library instead. - -wince*:contains(QT_CONFIG, opengles1) { - INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1 - LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES1 - for(p, QMAKE_LIBDIR_OPENGL_ES1) { - exists($$p):LIBS_PRIVATE += -L$$p - } - DEFINES += QT_GLES_EGL -} else { - INCLUDEPATH += $$QMAKE_INCDIR_EGL - LIBS_PRIVATE += $$QMAKE_LIBS_EGL - QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL - QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL - LIBS += $$QMAKE_LFLAGS_EGL - for(p, QMAKE_LIBDIR_EGL) { - exists($$p):LIBS_PRIVATE += -L$$p - } +INCLUDEPATH += $$QMAKE_INCDIR_EGL +LIBS_PRIVATE += $$QMAKE_LIBS_EGL +QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL +LIBS += $$QMAKE_LFLAGS_EGL +for(p, QMAKE_LIBDIR_EGL) { + exists($$p): LIBS_PRIVATE += -L$$p } diff --git a/mkspecs/features/opengles1.prf b/mkspecs/features/opengles1.prf deleted file mode 100644 index b09262f8a9..0000000000 --- a/mkspecs/features/opengles1.prf +++ /dev/null @@ -1,2 +0,0 @@ -QMAKE_LIBS_OPENGL_ES2 = -LIBS += $$QMAKE_LIBS_OPENGL_ES1 diff --git a/mkspecs/features/unix/opengl.prf b/mkspecs/features/unix/opengl.prf index 8dd47d089d..123c647be2 100644 --- a/mkspecs/features/unix/opengl.prf +++ b/mkspecs/features/unix/opengl.prf @@ -1,9 +1,4 @@ -contains(QT_CONFIG, opengles1) { - INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1 - !isEmpty(QMAKE_LIBDIR_OPENGL_ES1):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES1 - target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES1 - else:LIBS += $$QMAKE_LIBS_OPENGL_ES1 -} else:contains(QT_CONFIG, opengles2) { +contains(QT_CONFIG, opengles2) { INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2 !isEmpty(QMAKE_LIBDIR_OPENGL_ES2):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2 target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES2 diff --git a/mkspecs/hurd-g++/qmake.conf b/mkspecs/hurd-g++/qmake.conf index 261695f1ea..54a152de97 100644 --- a/mkspecs/hurd-g++/qmake.conf +++ b/mkspecs/hurd-g++/qmake.conf @@ -16,8 +16,6 @@ QMAKE_INCDIR_X11 = /usr/X11R6/include QMAKE_LIBDIR_X11 = /usr/X11R6/lib QMAKE_INCDIR_OPENGL = /usr/X11R6/include QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib -QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL -QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_EGL = @@ -31,7 +29,6 @@ QMAKE_LIBS_X11 = -lXext -lX11 -lm QMAKE_LIBS_NIS = -lnsl QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_OPENGL = -lGL -QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 QMAKE_LIBS_OPENVG = -lOpenVG QMAKE_LIBS_THREAD = -lpthread diff --git a/mkspecs/unsupported/android-g++/qmake.conf b/mkspecs/unsupported/android-g++/qmake.conf index 7ef85d4327..e52137d7c5 100644 --- a/mkspecs/unsupported/android-g++/qmake.conf +++ b/mkspecs/unsupported/android-g++/qmake.conf @@ -130,8 +130,6 @@ QMAKE_LIBDIR = ${ANDROID_PRODUCT_OUT}/obj/lib QMAKE_INCDIR_X11 = QMAKE_LIBDIR_X11 = QMAKE_INCDIR_OPENGL = -QMAKE_INCDIR_OPENGL_ES1 = -QMAKE_LIBDIR_OPENGL_ES1 = QMAKE_INCDIR_OPENGL_ES2 = QMAKE_LIBDIR_OPENGL_ES2 = @@ -172,7 +170,6 @@ QMAKE_LIBS_QT_OPENGL = QMAKE_LIBS_QTOPIA = QMAKE_LIBS_THREAD = QMAKE_LIBS_OPENGL = -QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM QMAKE_LIBS_OPENGL_ES2 = -lEGL -lGLESv2 $$QMAKE_LIBS CONFIG += linux-android-9 android-9 linux-android android android-no-sdk android_app diff --git a/mkspecs/unsupported/linux-host-g++/qmake.conf b/mkspecs/unsupported/linux-host-g++/qmake.conf index 586854d66c..3dc490d6dd 100644 --- a/mkspecs/unsupported/linux-host-g++/qmake.conf +++ b/mkspecs/unsupported/linux-host-g++/qmake.conf @@ -85,8 +85,6 @@ QMAKE_INCDIR_X11 = QMAKE_LIBDIR_X11 = QMAKE_INCDIR_OPENGL = QMAKE_LIBDIR_OPENGL = -QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL -QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL QMAKE_INCDIR_EGL = @@ -100,7 +98,6 @@ QMAKE_LIBS_X11 = -lXext -lX11 -lm QMAKE_LIBS_NIS = -lnsl QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_OPENGL = -lGL -QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 QMAKE_LIBS_OPENVG = -lOpenVG QMAKE_LIBS_THREAD = -lpthread diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index c1739982dc..91629ec9dd 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1696,11 +1696,10 @@ If the OpenGL implementation uses EGL (most OpenGL/ES systems), then QMAKE_INCDIR_EGL may also need to be set. - \section1 QMAKE_INCDIR_OPENGL_ES1, QMAKE_INCDIR_OPENGL_ES2 + \section1 QMAKE_INCDIR_OPENGL_ES2 - These variables specify the location of OpenGL headers files to be added - to \l{INCLUDEPATH} when building a target with OpenGL ES 1 - or OpenGL ES 2 support respectively. + This variable specifies the location of OpenGL header files to be added + to \l{INCLUDEPATH} when building a target with OpenGL ES 2 support. The value of this variable is typically handled by qmake or \l{#QMAKESPEC}{qmake.conf} and rarely diff --git a/src/gui/gui.pro b/src/gui/gui.pro index f083245809..c5262501ac 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -67,14 +67,7 @@ contains(QT_CONFIG, angle) { !isEmpty(QMAKE_LIBDIR_EGL): CMAKE_EGL_LIBDIR += $$cmakeTargetPath($$QMAKE_LIBDIR_EGL) } - contains(QT_CONFIG, opengles1) { - !isEmpty(QMAKE_INCDIR_OPENGL_ES1): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES1) - CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL_ES1) - CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL_ES1) - !isEmpty(QMAKE_LIBDIR_OPENGL_ES1): CMAKE_OPENGL_LIBDIR = $$cmakePortablePaths($$QMAKE_LIBDIR_OPENGL_ES1) - CMAKE_GL_HEADER_NAME = GLES/gl.h - CMAKE_QT_OPENGL_IMPLEMENTATION = GLES - } else:contains(QT_CONFIG, opengles2) { + contains(QT_CONFIG, opengles2) { !isEmpty(QMAKE_INCDIR_OPENGL_ES2): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES2) CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL_ES2) CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL_ES2) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 55fe036fe0..7a901a2877 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -1030,7 +1030,6 @@ void *QOpenGLContext::openGLModuleHandle() \value DesktopGL Desktop OpenGL \value GLES2 OpenGL ES 2.0 or higher - \value GLES1 OpenGL ES 1.x \since 5.3 */ @@ -1058,8 +1057,6 @@ QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType() return QGuiApplicationPrivate::instance()->platformIntegration()->openGLModuleType(); #elif defined(QT_OPENGL_ES_2) return GLES2; -#elif defined(QT_OPENGL_ES) - return GLES1; #else return DesktopGL; #endif diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index 06a7b723b4..fce983f975 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -196,8 +196,7 @@ public: enum OpenGLModuleType { DesktopGL, - GLES2, - GLES1 + GLES2 }; static OpenGLModuleType openGLModuleType(); diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp index 2e1a4577f6..a8a2255104 100644 --- a/src/gui/opengl/qopenglbuffer.cpp +++ b/src/gui/opengl/qopenglbuffer.cpp @@ -333,20 +333,18 @@ void QOpenGLBuffer::destroy() bool QOpenGLBuffer::read(int offset, void *data, int count) { #if !defined(QT_OPENGL_ES) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::GLES1) { - Q_D(QOpenGLBuffer); - if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) - return false; - while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state. - d->funcs->glGetBufferSubData(d->type, offset, count, data); - return d->funcs->glGetError() == GL_NO_ERROR; - } + Q_D(QOpenGLBuffer); + if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) + return false; + while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state. + d->funcs->glGetBufferSubData(d->type, offset, count, data); + return d->funcs->glGetError() == GL_NO_ERROR; #else Q_UNUSED(offset); Q_UNUSED(data); Q_UNUSED(count); -#endif return false; +#endif } /*! diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index ef0ef6d103..eb2c98e1f5 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -256,7 +256,7 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context) static int qt_gl_resolve_features() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->isES() && QOpenGLContext::openGLModuleType() != QOpenGLContext::GLES1) { + if (ctx->isES()) { // OpenGL ES 2 int features = QOpenGLFunctions::Multitexture | QOpenGLFunctions::Shaders | @@ -277,26 +277,6 @@ static int qt_gl_resolve_features() features |= QOpenGLFunctions::NPOTTextures | QOpenGLFunctions::NPOTTextureRepeat; return features; - } else if (ctx->isES()) { - // OpenGL ES 1 - int features = QOpenGLFunctions::Multitexture | - QOpenGLFunctions::Buffers | - QOpenGLFunctions::CompressedTextures | - QOpenGLFunctions::Multisample; - QOpenGLExtensionMatcher extensions; - if (extensions.match("GL_OES_framebuffer_object")) - features |= QOpenGLFunctions::Framebuffers; - if (extensions.match("GL_OES_blend_equation_separate")) - features |= QOpenGLFunctions::BlendEquationSeparate; - if (extensions.match("GL_OES_blend_func_separate")) - features |= QOpenGLFunctions::BlendFuncSeparate; - if (extensions.match("GL_OES_blend_subtract")) - features |= QOpenGLFunctions::BlendSubtract; - if (extensions.match("GL_OES_texture_npot")) - features |= QOpenGLFunctions::NPOTTextures; - if (extensions.match("GL_IMG_texture_npot")) - features |= QOpenGLFunctions::NPOTTextures; - return features; } else { // OpenGL int features = 0; diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 4d9208d983..5cd553a5e8 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -11,7 +11,6 @@ QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf load(qt_module) contains(QT_CONFIG, opengl):CONFIG += opengl -contains(QT_CONFIG, opengles1):CONFIG += opengles1 contains(QT_CONFIG, opengles2):CONFIG += opengles2 contains(QT_CONFIG, egl):CONFIG += egl diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index 0bcb9d4f1f..1c9545990f 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -344,20 +344,18 @@ void QGLBuffer::destroy() bool QGLBuffer::read(int offset, void *data, int count) { #if !defined(QT_OPENGL_ES) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::GLES1) { - Q_D(QGLBuffer); - if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) - return false; - while (glGetError() != GL_NO_ERROR) ; // Clear error state. - d->funcs->glGetBufferSubData(d->type, offset, count, data); - return glGetError() == GL_NO_ERROR; - } + Q_D(QGLBuffer); + if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) + return false; + while (glGetError() != GL_NO_ERROR) ; // Clear error state. + d->funcs->glGetBufferSubData(d->type, offset, count, data); + return glGetError() == GL_NO_ERROR; #else Q_UNUSED(offset); Q_UNUSED(data); Q_UNUSED(count); -#endif return false; +#endif } /*! diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index d6d77d0568..42b3b47f7f 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -223,7 +223,7 @@ QGLFunctions::QGLFunctions(const QGLContext *context) static int qt_gl_resolve_features() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->isES() && QOpenGLContext::openGLModuleType() != QOpenGLContext::GLES1) { + if (ctx->isES()) { // OpenGL ES 2 int features = QGLFunctions::Multitexture | QGLFunctions::Shaders | @@ -243,26 +243,6 @@ static int qt_gl_resolve_features() if (extensions.match("GL_IMG_texture_npot")) features |= QGLFunctions::NPOTTextures; return features; - } else if (ctx->isES()) { - // OpenGL ES 1 - int features = QGLFunctions::Multitexture | - QGLFunctions::Buffers | - QGLFunctions::CompressedTextures | - QGLFunctions::Multisample; - QOpenGLExtensionMatcher extensions; - if (extensions.match("GL_OES_framebuffer_object")) - features |= QGLFunctions::Framebuffers; - if (extensions.match("GL_OES_blend_equation_separate")) - features |= QGLFunctions::BlendEquationSeparate; - if (extensions.match("GL_OES_blend_func_separate")) - features |= QGLFunctions::BlendFuncSeparate; - if (extensions.match("GL_OES_blend_subtract")) - features |= QGLFunctions::BlendSubtract; - if (extensions.match("GL_OES_texture_npot")) - features |= QGLFunctions::NPOTTextures; - if (extensions.match("GL_IMG_texture_npot")) - features |= QGLFunctions::NPOTTextures; - return features; } else { // OpenGL int features = 0; diff --git a/src/openglextensions/openglextensions.pro b/src/openglextensions/openglextensions.pro index e303dea5e8..948465165e 100644 --- a/src/openglextensions/openglextensions.pro +++ b/src/openglextensions/openglextensions.pro @@ -2,7 +2,6 @@ TARGET = QtOpenGLExtensions CONFIG += static contains(QT_CONFIG, opengl):CONFIG += opengl -contains(QT_CONFIG, opengles1):CONFIG += opengles1 contains(QT_CONFIG, opengles2):CONFIG += opengles2 load(qt_module) diff --git a/src/src.pro b/src/src.pro index 0d854a85c1..6a805a6a06 100644 --- a/src/src.pro +++ b/src/src.pro @@ -142,13 +142,13 @@ contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent src_gui.depends += src_angle } SUBDIRS += src_gui src_platformsupport - contains(QT_CONFIG, opengl(es1|es2)?):SUBDIRS += src_openglextensions + contains(QT_CONFIG, opengl(es2)?):SUBDIRS += src_openglextensions src_plugins.depends += src_gui src_platformsupport !contains(QT_CONFIG, no-widgets) { SUBDIRS += src_tools_uic src_widgets TOOLS += src_tools_uic src_plugins.depends += src_widgets - contains(QT_CONFIG, opengl(es1|es2)?):!contains(QT_CONFIG, dynamicgl) { + contains(QT_CONFIG, opengl(es2)?):!contains(QT_CONFIG, dynamicgl) { SUBDIRS += src_opengl src_plugins.depends += src_opengl } diff --git a/tests/auto/cmake/test_opengl_lib/CMakeLists.txt b/tests/auto/cmake/test_opengl_lib/CMakeLists.txt index d602bcda9b..d9adb5a980 100644 --- a/tests/auto/cmake/test_opengl_lib/CMakeLists.txt +++ b/tests/auto/cmake/test_opengl_lib/CMakeLists.txt @@ -10,9 +10,7 @@ add_definitions(${Qt5Gui_DEFINITIONS}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS}") -if (${Qt5Gui_OPENGL_IMPLEMENTATION} STREQUAL GLES) - add_definitions(-DGL_IMPLEMENTATION_GLES1) -elseif (${Qt5Gui_OPENGL_IMPLEMENTATION} STREQUAL GLESv2) +if (${Qt5Gui_OPENGL_IMPLEMENTATION} STREQUAL GLESv2) add_definitions(-DGL_IMPLEMENTATION_GLES2) elseif (${Qt5Gui_OPENGL_IMPLEMENTATION} STREQUAL GL) add_definitions(-DGL_IMPLEMENTATION_GL) diff --git a/tests/auto/cmake/test_opengl_lib/main.cpp b/tests/auto/cmake/test_opengl_lib/main.cpp index 450b759bc8..1e874ed4fc 100644 --- a/tests/auto/cmake/test_opengl_lib/main.cpp +++ b/tests/auto/cmake/test_opengl_lib/main.cpp @@ -40,9 +40,7 @@ ****************************************************************************/ -#if GL_IMPLEMENTATION_GLES1 -#include -#elif GL_IMPLEMENTATION_GLES2 +#if GL_IMPLEMENTATION_GLES2 #include #elif GL_IMPLEMENTATION_GL diff --git a/tests/auto/gui/gui.pro b/tests/auto/gui/gui.pro index d250e45a4e..78386cc0b1 100644 --- a/tests/auto/gui/gui.pro +++ b/tests/auto/gui/gui.pro @@ -12,4 +12,4 @@ SUBDIRS = \ util \ itemmodels \ -!contains(QT_CONFIG, opengl(es1|es2)?): SUBDIRS -= qopengl +!contains(QT_CONFIG, opengl(es2)?): SUBDIRS -= qopengl diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index bb09a19e55..76072121aa 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -676,9 +676,6 @@ void Configure::parseCmdLine() else if (configCmdLine.at(i) == "-no-opengl") { dictionary[ "OPENGL" ] = "no"; dictionary[ "OPENGL_ES_2" ] = "no"; - } else if (configCmdLine.at(i) == "-opengl-es-cm") { - dictionary[ "OPENGL" ] = "yes"; - dictionary[ "OPENGL_ES_CM" ] = "yes"; } else if (configCmdLine.at(i) == "-opengl-es-2") { dictionary[ "OPENGL" ] = "yes"; dictionary[ "OPENGL_ES_2" ] = "yes"; @@ -689,9 +686,7 @@ void Configure::parseCmdLine() break; dictionary[ "OPENGL_ES_2" ] = "no"; - if (configCmdLine.at(i) == "es1") { - dictionary[ "OPENGL_ES_CM" ] = "yes"; - } else if ( configCmdLine.at(i) == "es2" ) { + if ( configCmdLine.at(i) == "es2" ) { dictionary[ "OPENGL_ES_2" ] = "yes"; } else if ( configCmdLine.at(i) == "desktop" ) { // OPENGL=yes suffices @@ -1819,7 +1814,6 @@ bool Configure::displayHelp() "Available values for :"); desc("", "no", "", " desktop - Enable support for Desktop OpenGL", ' '); desc("", "no", "", " dynamic - Enable support for dynamically loaded OpenGL (either desktop or ES)", ' '); - desc("OPENGL_ES_CM", "no", "", " es1 - Enable support for OpenGL ES Common Profile", ' '); desc("OPENGL_ES_2", "yes", "", " es2 - Enable support for OpenGL ES 2.0\n", ' '); desc("OPENVG", "no","-no-openvg", "Disables OpenVG functionality."); @@ -2213,8 +2207,6 @@ bool Configure::checkAvailability(const QString &part) available = findFile("ibase.h") && (findFile("gds32_ms.lib") || findFile("gds32.lib")); else if (part == "IWMMXT") available = (dictionary.value("XQMAKESPEC").startsWith("wince")); - else if (part == "OPENGL_ES_CM") - available = (dictionary.value("XQMAKESPEC").startsWith("wince")); else if (part == "OPENGL_ES_2") available = (dictionary.value("XQMAKESPEC").startsWith("wince")); else if (part == "SSE2") @@ -2784,11 +2776,6 @@ void Configure::generateOutputVars() if (dictionary[ "OPENGL" ] == "yes") qtConfig += "opengl"; - if (dictionary["OPENGL_ES_CM"] == "yes") { - qtConfig += "opengles1"; - qtConfig += "egl"; - } - if (dictionary["OPENGL_ES_2"] == "yes") { qtConfig += "opengles2"; qtConfig += "egl"; @@ -3500,10 +3487,7 @@ void Configure::generateConfigfiles() if (dictionary["HARFBUZZ"] == "no") qconfigList += "QT_NO_HARFBUZZ"; if (dictionary["NATIVE_GESTURES"] == "no") qconfigList += "QT_NO_NATIVE_GESTURES"; - if (dictionary["OPENGL_ES_CM"] == "yes" || - dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES"; - - if (dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1"; + if (dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES"; if (dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2"; if (dictionary["DYNAMICGL"] == "yes") qconfigList += "QT_OPENGL_DYNAMIC"; if (dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL"; -- cgit v1.2.3 From fb143abbfb28d8433b908b09b37b4c7720357892 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Apr 2014 20:38:57 +0200 Subject: de-duplicate code Change-Id: Ic056acf739659215241c1cab6a462b1ab591dc78 Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 36f808197a..5ae99bab92 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1277,9 +1277,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnFalse; } int cnt = values(map(args.at(0))).count(); + int val = args.at(1).toQString(m_tmp1).toInt(); if (args.count() == 3) { const ProString &comp = args.at(2); - const int val = args.at(1).toQString(m_tmp1).toInt(); if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) { return returnBool(cnt > val); } else if (comp == QLatin1String(">=")) { @@ -1290,13 +1290,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return returnBool(cnt <= val); } else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual") || comp == QLatin1String("=") || comp == QLatin1String("==")) { - return returnBool(cnt == val); + // fallthrough } else { evalError(fL1S("Unexpected modifier to count(%2).").arg(comp.toQString(m_tmp1))); return ReturnFalse; } } - return returnBool(cnt == args.at(1).toQString(m_tmp1).toInt()); + return returnBool(cnt == val); } case T_GREATERTHAN: case T_LESSTHAN: { -- cgit v1.2.3 From 2343b74193ed87f5c474efd6055b54edf3ffd91a Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Fri, 4 Apr 2014 11:04:08 +0200 Subject: Doc: Fix documentation warning in qstylehints.cpp warning: Command '\snippet (//! [6])' failed at end of file 'code/src_gui_kernel_qguiapplication.cpp' This change amends 56cd9cc2b085c1a2152831d47bb8fd9607d7500e Change-Id: I63a2f086fc582d3a9c8b60f1ef94ccb537b0d3a5 Reviewed-by: Samuel Gaist Reviewed-by: Sze Howe Koh Reviewed-by: Jerome Pasion --- src/gui/kernel/qstylehints.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp index e1468942af..ac638f4905 100644 --- a/src/gui/kernel/qstylehints.cpp +++ b/src/gui/kernel/qstylehints.cpp @@ -163,7 +163,7 @@ void QStyleHints::setStartDragDistance(int startDragDistance) and the current position (e.g. in the mouse move event) is \c currentPos, you can find out if a drag should be started with code like this: - \snippet code/src_gui_kernel_qguiapplication.cpp 6 + \snippet code/src_gui_kernel_qapplication.cpp 6 \sa startDragTime(), QPoint::manhattanLength(), {Drag and Drop} */ -- cgit v1.2.3 From 1a6d7b6e93455064229edd6e64f6fac65c22cb61 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Wed, 2 Apr 2014 12:58:26 +0300 Subject: Fix neon image scaling function declarations Change on the image scaling functions did not update the neon function declarations. Task-number: QTBUG-35927 Change-Id: Ia1e7428953aa140cad36e1cf26a18bfefc2267e7 Reviewed-by: Laszlo Agocs Reviewed-by: Lars Knoll --- src/gui/painting/qdrawhelper_neon_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h index cad6fe22e9..2313664846 100644 --- a/src/gui/painting/qdrawhelper_neon_p.h +++ b/src/gui/painting/qdrawhelper_neon_p.h @@ -96,14 +96,14 @@ void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, const QClipData *clip); void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, + const uchar *srcPixels, int sbpl, int srch, const QRectF &targetRect, const QRectF &sourceRect, const QRect &clip, int const_alpha); void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, + const uchar *srcPixels, int sbpl, int srch, const QRectF &targetRect, const QRectF &sourceRect, const QRect &clip, -- cgit v1.2.3 From 8d83562c1f4e37875d00761219968431e18a7704 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Fri, 4 Apr 2014 18:06:50 +0200 Subject: QNX: Surpress manual window activation during showFullScreen When a window is shown, libscreen will give it keyboard focus. Requesting the activation right after the window is created (and before libscreen activated the window) causes problems on some devices e.g. Q10. Change-Id: I29f7a38990ea4259a8b0c6624f70e31d7291af00 Reviewed-by: Sergio Ahumada --- src/gui/kernel/qwindow.cpp | 3 +++ src/widgets/kernel/qwidget.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 13da58e391..6dcc3df166 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1751,7 +1751,10 @@ void QWindow::showFullScreen() { setWindowState(Qt::WindowFullScreen); setVisible(true); +#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen + // activating it here before libscreen activates it causes problems requestActivate(); +#endif } /*! diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 03655639d5..5bcec13238 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -2837,7 +2837,10 @@ void QWidget::showFullScreen() setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized)) | Qt::WindowFullScreen); setVisible(true); +#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen + // activating it here before libscreen activates it causes problems activateWindow(); +#endif } /*! -- cgit v1.2.3 From 6c8ecf1000a5defef40348bfda5527dabb57ecf4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 2 Apr 2014 15:01:56 -0700 Subject: Consistently hide the parts that require xcb-xkb It was inconsistent. This also solves a warning from Clang 3.4: error: private field 'vmod_masks' is not used [-Werror,-Wunused-private-field] Change-Id: I6be9f7ef56dffe6df2be3beb984c2d82d3808403 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 2 +- src/plugins/platforms/xcb/qxcbkeyboard.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 4ee1cb4305..d5c876624a 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -976,10 +976,10 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection) , xkb_context(0) , xkb_keymap(0) , xkb_state(0) - , core_device_id(0) { memset(&xkb_names, 0, sizeof(xkb_names)); #ifndef QT_NO_XKB + core_device_id = 0; if (connection->hasXKB()) { updateVModMapping(); updateVModToRModMapping(); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index ce27785ae1..11b7429aca 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -76,9 +76,9 @@ public: void updateXKBMods(); quint32 xkbModMask(quint16 state); void updateXKBStateFromCore(quint16 state); +#ifndef QT_NO_XKB // when XKEYBOARD is present on the X server int coreDeviceId() const { return core_device_id; } -#ifndef QT_NO_XKB void updateXKBState(xcb_xkb_state_notify_event_t *state); #endif @@ -131,9 +131,11 @@ private: xkb_mod_index_t mod5; }; _xkb_mods xkb_mods; +#ifndef QT_NO_XKB // when XKEYBOARD is present on the X server _mod_masks vmod_masks; int core_device_id; +#endif }; QT_END_NAMESPACE -- cgit v1.2.3 From 3e930baa98b4382b76aea5ed6ffdcfb60cdce2d4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 2 Apr 2014 14:41:00 -0700 Subject: Use Q_STATIC_ASSERT to check that the array has the right size No need to sprinkle the code with Q_ASSERT. We don't want this to fail to the user anyway. By using a Q_STATIC_ASSERT, a failure will be immediately reported to the developer. This also solves a warning found by Clang 3.4: error: unused variable 'pageSizesCount' [-Werror,-Wunused-const-variable] Change-Id: I79cf72c64242ad395276ce4360c59ad81112d9eb Reviewed-by: Lars Knoll --- src/gui/painting/qpagesize.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp index 6698d77bbd..7d19d49b4e 100644 --- a/src/gui/painting/qpagesize.cpp +++ b/src/gui/painting/qpagesize.cpp @@ -389,18 +389,17 @@ static const StandardPageSize qt_pageSizes[] = { }; static const int pageSizesCount = int(sizeof(qt_pageSizes) / sizeof(qt_pageSizes[0])); +Q_STATIC_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); // Return key name for PageSize static QString qt_keyForPageSizeId(QPageSize::PageSizeId id) { - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); return QString::fromLatin1(qt_pageSizes[id].mediaOption); } // Return id name for PPD Key static QPageSize::PageSizeId qt_idForPpdKey(const QString &ppdKey, QSize *match = 0) { - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); if (ppdKey.isEmpty()) return QPageSize::Custom; QString key = ppdKey; @@ -422,7 +421,6 @@ static QPageSize::PageSizeId qt_idForPpdKey(const QString &ppdKey, QSize *match // Return id name for Windows ID static QPageSize::PageSizeId qt_idForWindowsID(int windowsId, QSize *match = 0) { - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); // If outside known values then is Custom if (windowsId <= DMPAPER_NONE || windowsId > DMPAPER_LAST) return QPageSize::Custom; @@ -536,7 +534,6 @@ Q_GUI_EXPORT qreal qt_pixelMultiplier(int resolution) static QSizeF qt_definitionSize(QPageSize::PageSizeId pageSizeId) { - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); QPageSize::Unit units = qt_pageSizes[pageSizeId].definitionUnits; if (units == QPageSize::Millimeter) return QSizeF(qt_pageSizes[pageSizeId].widthMillimeters, qt_pageSizes[pageSizeId].heightMillimeters); @@ -595,7 +592,6 @@ static QSizeF qt_convertPointsToUnits(const QSize &size, QPageSize::Unit units) static QSizeF qt_unitSize(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units) { - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); switch (units) { case QPageSize::Millimeter: return QSizeF(qt_pageSizes[pageSizeId].widthMillimeters, qt_pageSizes[pageSizeId].heightMillimeters); @@ -619,7 +615,6 @@ static QPageSize::PageSizeId qt_idForPointSize(const QSize &size, QPageSize::Siz return QPageSize::Custom; // Try exact match in portrait layout - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); for (int i = 0; i <= int(QPageSize::LastPageSize); ++i) { if (size.width() == qt_pageSizes[i].widthPoints && size.height() == qt_pageSizes[i].heightPoints) { if (match) @@ -687,7 +682,6 @@ static QPageSize::PageSizeId qt_idForSize(const QSizeF &size, QPageSize::Unit un return QPageSize::Custom; // Try exact match if units are the same - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); if (units == QPageSize::Millimeter) { for (int i = 0; i <= QPageSize::LastPageSize; ++i) { if (size.width() == qt_pageSizes[i].widthMillimeters && size.height() == qt_pageSizes[i].heightMillimeters) { @@ -834,7 +828,6 @@ QPageSizePrivate::~QPageSizePrivate() // Init a standard PageSizeId void QPageSizePrivate::init(QPageSize::PageSizeId id, const QString &name) { - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); m_id = id; m_size = qt_definitionSize(id); m_units = qt_pageSizes[id].definitionUnits; @@ -1480,7 +1473,6 @@ QString QPageSize::key(QPageSize::PageSizeId pageSizeId) { if (pageSizeId < QPageSize::PageSizeId(0) || pageSizeId > QPageSize::LastPageSize) return QString(); - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); return QString::fromUtf8(qt_pageSizes[pageSizeId].mediaOption); } @@ -1795,7 +1787,6 @@ QPageSize::PageSizeId QPageSize::id(int windowsId) int QPageSize::windowsId(QPageSize::PageSizeId pageSizeId) { - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); return qt_pageSizes[pageSizeId].windowsId; } @@ -1822,7 +1813,6 @@ QPageSize::Unit QPageSize::definitionUnits(QPageSize::PageSizeId pageSizeId) { if (pageSizeId == QPageSize::Custom) return QPageSize::Unit(-1); - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); return qt_pageSizes[pageSizeId].definitionUnits; } @@ -1845,7 +1835,6 @@ QSize QPageSize::sizePoints(QPageSize::PageSizeId pageSizeId) { if (pageSizeId == QPageSize::Custom) return QSize(); - Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1); return QSize(qt_pageSizes[pageSizeId].widthPoints, qt_pageSizes[pageSizeId].heightPoints); } -- cgit v1.2.3 From f1540a2966ce911e9a5d5754e53f6026e3c26d22 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 24 Mar 2014 12:53:27 -0700 Subject: Fix capacity reservation for shared QByteArray MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can squeeze, but not by discarding elements. Make sure the size of the object stays intact after changing the reserved capacity. I've also added unit tests for other containers, just to be sure. Task-number: QTBUG-37750 Change-Id: I5135b095943b7589423c51cebcb52af792468e61 Reviewed-by: Marc Mutz Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qbytearray.h | 2 +- .../corelib/tools/qbytearray/tst_qbytearray.cpp | 15 ++++++++++++ tests/auto/corelib/tools/qlist/tst_qlist.cpp | 28 ++++++++++++++++++++++ tests/auto/corelib/tools/qstring/tst_qstring.cpp | 9 +++++++ tests/auto/corelib/tools/qvector/tst_qvector.cpp | 1 + 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index b0a6971964..0a2f7a9e53 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -462,7 +462,7 @@ inline int QByteArray::capacity() const inline void QByteArray::reserve(int asize) { if (d->ref.isShared() || uint(asize) + 1u > d->alloc) { - reallocData(uint(asize) + 1u, d->detachFlags() | Data::CapacityReserved); + reallocData(qMax(uint(size()), uint(asize)) + 1u, d->detachFlags() | Data::CapacityReserved); } else { // cannot set unconditionally, since d could be the shared_null or // otherwise static diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index b06741b23e..6e183f3212 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -1855,6 +1855,21 @@ void tst_QByteArray::reserve() QVERIFY(data == qba.data()); } + qba.resize(capacity); + + QByteArray copy = qba; + qba.reserve(capacity / 2); + QCOMPARE(qba.size(), capacity); // we didn't shrink the size! + QCOMPARE(qba.capacity(), capacity); + QCOMPARE(copy.capacity(), capacity); + + copy = qba; + qba.reserve(capacity * 2); + QCOMPARE(qba.size(), capacity); + QCOMPARE(qba.capacity(), capacity * 2); + QCOMPARE(copy.capacity(), capacity); + QVERIFY(qba.constData() != data); + QByteArray nil1, nil2; nil1.reserve(0); nil2.squeeze(); diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index 2c9bf9d4c9..d77cc4a37c 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -278,6 +278,8 @@ private slots: void setSharableComplex() const; void eraseValidIteratorsOnSharedList() const; void insertWithValidIteratorsOnSharedList() const; + + void reserve() const; private: template void length() const; template void append() const; @@ -1669,5 +1671,31 @@ void tst_QList::insertWithValidIteratorsOnSharedList() const QCOMPARE(a.at(1), 15); } +void tst_QList::reserve() const +{ + // Note: + // This test depends on QList's current behavior that ints are stored in the array itself. + // This test would not work for QList. + int capacity = 100; + QList list; + list.reserve(capacity); + list << 0; + int *data = &list[0]; + + for (int i = 1; i < capacity; i++) { + list << i; + QCOMPARE(&list.at(0), data); + } + + QList copy = list; + list.reserve(capacity / 2); + QCOMPARE(list.size(), capacity); // we didn't shrink the size! + + copy = list; + list.reserve(capacity * 2); + QCOMPARE(list.size(), capacity); + QVERIFY(&list.at(0) != data); +} + QTEST_APPLESS_MAIN(tst_QList) #include "tst_qlist.moc" diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 5655d9f529..d9d6b985b7 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -4277,14 +4277,23 @@ void tst_QString::capacity() QVERIFY( (int)s2.capacity() >= res ); QCOMPARE( s2, s1 ); + s2 = s1; // share again s2.reserve( res * 2 ); QVERIFY( (int)s2.capacity() >= res * 2 ); + QVERIFY(s2.constData() != s1.constData()); QCOMPARE( s2, s1 ); + // don't share again -- s2 must be detached for squeeze() to do anything s2.squeeze(); QVERIFY( (int)s2.capacity() == res ); QCOMPARE( s2, s1 ); + s2 = s1; // share again + int oldsize = s1.size(); + s2.reserve( res / 2 ); + QVERIFY( (int)s2.capacity() >= res / 2 ); + QVERIFY( (int)s2.capacity() >= oldsize ); + QCOMPARE( s2, s1 ); } void tst_QString::section_data() diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 59956e33cf..c9545c8eb4 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -1942,6 +1942,7 @@ void tst_QVector::reserve() a.resize(2); QVector b(a); b.reserve(1); + QCOMPARE(b.size(), a.size()); } QCOMPARE(fooCtor, fooDtor); } -- cgit v1.2.3 From d24ada47b482a9db2e004afcd54427d2b1c46846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 20 Mar 2014 22:05:59 +0100 Subject: Cocoa: Support pasting rich text to Qt apps Native Mac OS X apps uses Rtf as the rich text format while Qt uses html. Add QMacPasteboardMimeRtfText which supports converting from public.rtf to text/html (but not the other way around, since we want to keep posting our html as html). The QMacInternalPasteboardMime API does not support the concept of a one-way handler. Skip the Rtf handler in QMacPasteboard::setMimeData(). Task-number: QTBUG-37188 Change-Id: Ibe29997a038bbb64da24b961e84a5f60133074e0 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoamimetypes.mm | 67 ++++++++++++++++++++++++++ src/plugins/platforms/cocoa/qmacclipboard.mm | 5 ++ 2 files changed, 72 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm index 05d4c19112..8151d31449 100644 --- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm +++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm @@ -136,9 +136,76 @@ QList QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q return ret; } +// This handler is special: It supports converting public.rtf top text/html, +// but not the other way around. +class QMacPasteboardMimeRtfText : public QMacInternalPasteboardMime { +public: + QMacPasteboardMimeRtfText() : QMacInternalPasteboardMime(MIME_ALL) { } + QString convertorName(); + + QString flavorFor(const QString &mime); + QString mimeFor(QString flav); + bool canConvert(const QString &mime, QString flav); + QVariant convertToMime(const QString &mime, QList data, QString flav); + QList convertFromMime(const QString &mime, QVariant data, QString flav); +}; + +QString QMacPasteboardMimeRtfText::convertorName() +{ + return QLatin1String("Rtf"); +} + +QString QMacPasteboardMimeRtfText::flavorFor(const QString &mime) +{ + if (mime == QLatin1String("text/html")) + return QLatin1String("public.rtf"); + return QString(); +} + +QString QMacPasteboardMimeRtfText::mimeFor(QString flav) +{ + if (flav == QLatin1String("public.rtf")) + return QLatin1String("text/html"); + return QString(); +} + +bool QMacPasteboardMimeRtfText::canConvert(const QString &mime, QString flav) +{ + return flavorFor(mime) == flav; +} + +QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList data, QString flavor) +{ + if (!canConvert(mimeType, flavor)) + return QVariant(); + if (data.count() > 1) + qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data"); + + // Convert Rtf to Html. + NSAttributedString *string = [[NSAttributedString alloc] initWithRTF:data.at(0).toNSData() documentAttributes:NULL]; + NSError *error; + NSRange range = NSMakeRange(0,[string length]); + NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute]; + NSData *htmldata = [string dataFromRange:range documentAttributes:dict error:&error]; + [string release]; + return QByteArray::fromNSData(htmldata); +} + +QList QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor) +{ + Q_UNUSED(mime); + Q_UNUSED(data); + Q_UNUSED(flavor); + + qWarning("QMacPasteboardMimeRtfText: Conversion from Html to Rtf is not supported"); + QList ret; + return ret; +} + void QCocoaMimeTypes::initializeMimeTypes() { new QMacPasteboardMimeTiff; + new QMacPasteboardMimeRtfText; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index 9368b65866..6549f127b6 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -305,6 +305,11 @@ QMacPasteboard::setMimeData(QMimeData *mime_src) QString mimeType = formats.at(f); for (QList::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) { QMacInternalPasteboardMime *c = (*it); + // Hack: The Rtf handler converts incoming Rtf to Html. We do + // not want to convert outgoing Html to Rtf but instead keep + // posting it as Html. Skip the Rtf handler here. + if (c->convertorName() == QStringLiteral("Rtf")) + continue; QString flavor(c->flavorFor(mimeType)); if (!flavor.isEmpty()) { QVariant mimeData = static_cast(mime_src)->variantData(mimeType); -- cgit v1.2.3 From bb73d8d0704fbef9bd54fedccfe1e4647f3063cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 31 Mar 2014 12:38:35 +0200 Subject: Compile: isChildOfQMdiSubWindow may be unused. [-Werror,-Wunused-function] Change-Id: Icf1e60ce3c5dadb96272453583d1cd03379eb73b Reviewed-by: Thiago Macieira --- src/widgets/widgets/qmdisubwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index 94674319bc..b1adb3f760 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -1761,11 +1761,13 @@ bool QMdiSubWindowPrivate::drawTitleBarWhenMaximized() const return false; #if defined(Q_OS_MAC) && !defined(QT_NO_STYLE_MAC) || defined(Q_OS_WINCE_WM) + Q_UNUSED(isChildOfQMdiSubWindow); return true; #else if (q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) return true; #if defined(QT_NO_MENUBAR) || defined(QT_NO_MAINWINDOW) + Q_UNUSED(isChildOfQMdiSubWindow); return true; #else QMainWindow *mainWindow = qobject_cast(q->window()); -- cgit v1.2.3 From bd2ec12a7b2787638aa3f7932c20ae4d6577734e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 2 Apr 2014 12:35:09 +0200 Subject: Cocoa: Make QScreen::topLevelAt() work correctly The QPlatformScreen::topLevelAt() default implementation is flawed in that it does not check z-ordering but simply returns the first window in the window list that contains the test point. Add QCocoaScreen::topLevelAt(). Use [NSApp orderedWindows] to iterate through the window list in z order. Add a NSWindow->QCococaWindow mapping hash to QCocoaIntegration for getting the corresponding QWindow once a NSWindow is found. Task-number: QTBUG-37597 Change-Id: I7af70163a32528cb56f8d6caa037b98f580ee191 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoaintegration.h | 4 ++++ src/plugins/platforms/cocoa/qcocoaintegration.mm | 28 ++++++++++++++++++++++++ src/plugins/platforms/cocoa/qcocoawindow.mm | 5 +++++ 3 files changed, 37 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 24adc7a95b..9c4f86d893 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -80,6 +80,7 @@ public: qreal refreshRate() const { return m_refreshRate; } QString name() const { return m_name; } QPlatformCursor *cursor() const { return m_cursor; } + QWindow *topLevelAt(const QPoint &point) const; QList virtualSiblings() const { return m_siblings; } // ---------------------------------------------------- @@ -138,6 +139,8 @@ public: void setToolbar(QWindow *window, NSToolbar *toolbar); NSToolbar *toolbar(QWindow *window) const; void clearToolbars(); + void setWindow(NSWindow* nsWindow, QCocoaWindow *window); + QCocoaWindow *window(NSWindow *window); private: static QCocoaIntegration *mInstance; @@ -156,6 +159,7 @@ private: QScopedPointer mKeyboardMapper; QHash mToolbars; + QHash mWindows; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 9d5388d33b..c4398622e8 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -156,6 +156,24 @@ qreal QCocoaScreen::devicePixelRatio() const } } +QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const +{ + // Get a z-ordered list of windows. Iterate through it until + // we find a window which contains the point. + for (NSWindow *nsWindow in [NSApp orderedWindows]) { + QCocoaWindow *cocoaWindow = QCocoaIntegration::instance()->window(nsWindow); + if (!cocoaWindow) + continue; + QWindow *window = cocoaWindow->window(); + if (!window->isTopLevel()) + continue; + if (window->geometry().contains(point)) + return window; + } + + return QPlatformScreen::topLevelAt(point); +} + extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const @@ -500,6 +518,16 @@ NSToolbar *QCocoaIntegration::toolbar(QWindow *window) const return mToolbars.value(window); } +void QCocoaIntegration::setWindow(NSWindow* nsWindow, QCocoaWindow *window) +{ + mWindows.insert(nsWindow, window); +} + +QCocoaWindow *QCocoaIntegration::window(NSWindow *window) +{ + return mWindows.value(window); +} + void QCocoaIntegration::clearToolbars() { QHash::const_iterator it = mToolbars.constBegin(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index df15b008ab..f9a94d6b51 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -261,6 +261,8 @@ static bool isMouseEvent(NSEvent *ev) { [self close]; + QCocoaIntegration::instance()->setWindow(self, 0); + if (self.helper.grabbingMouse) { self.helper.releaseOnMouseUp = YES; } else { @@ -327,6 +329,7 @@ static bool isMouseEvent(NSEvent *ev) { [self.helper detachFromPlatformWindow]; [self close]; + QCocoaIntegration::instance()->setWindow(self, 0); [self release]; } @@ -1402,6 +1405,8 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow() applyContentBorderThickness(createdWindow); + QCocoaIntegration::instance()->setWindow(createdWindow, this); + return createdWindow; } -- cgit v1.2.3 From a7e8b400d1ca6cf4e23b02564812ea3ff0bb9015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 2 Apr 2014 08:20:54 +0200 Subject: Cocoa: Make backing store flush accurate. Flush the individual rects that make up the region instead of the bounding rect. This is required for correctness since then areas not included in the region might not have valid backing store content. The bondingRect() usage here had its roots in an optimization in Qt 4, where it was observed that flushing the bounding rect was more efficient than flushing (many) individual rects. Task-number: QTBUG-37918 Change-Id: Ib805f6713523f9895be24c48466870efaaf89c02 Reviewed-by: Liang Qi Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 1197aa9148..e17cd0a4cc 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -371,8 +371,9 @@ static QTouchDevice *touchDevice = 0; { m_backingStore = backingStore; m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio(); - QRect br = region.boundingRect(); - [self setNeedsDisplayInRect:NSMakeRect(br.x(), br.y(), br.width(), br.height())]; + foreach (QRect rect, region.rects()) { + [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; + } } - (BOOL) hasMask -- cgit v1.2.3 From 840a66501776b992623734ee37be0a46ecc42484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 2 Apr 2014 13:33:53 +0200 Subject: Cocoa: Don't beep on maximize. Use zoom instead of performZoom: Does not beep if there is no Zoom button, and is what Qt 4 did. Task-number: QTBUG-37716 Change-Id: Iaa85d55a449744c38b260cf79745a433e0e3272f Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoawindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index f9a94d6b51..666e18715f 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1473,7 +1473,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) { if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) { - [m_nsWindow performZoom : m_nsWindow]; // toggles + [m_nsWindow zoom : m_nsWindow]; // toggles m_effectivelyMaximized = !m_effectivelyMaximized; } else if (!(newState & Qt::WindowMaximized)) { // it would be nice to change the target geometry that toggleFullScreen will animate toward -- cgit v1.2.3 From 2884d7c9aafda5ad2d84f1c7a1b4ea2625182885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 2 Apr 2014 23:16:28 +0200 Subject: OS X: Improve QLibraryInfo app bundle testing. QLibraryInfo::location() paths are relative to "myapp.app/Contents/" when the application has a bundle and relative to the executable when not. However CFBundleGetMainBundle() can and will return a valid CFBundleRef even if the application is built as a standalone executable. Add a test that verifies that the path constructed with "/Contents" exists on disk. Fall back to the non-bundle code path if it doesn't. This bug was hit in cases where a qt.conf file was present side-by-side with the app binary, for example in qtbase/bin. Task-number: QTBUG-38039 Change-Id: Id993599208fe94fff283c725778f8ad47b610ba7 Reviewed-by: Eike Ziller Reviewed-by: Gabriel de Dietrich Reviewed-by: Oswald Buddenhagen --- src/corelib/global/qlibraryinfo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 39bfd339c3..6d25325890 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -498,7 +498,9 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) if (urlRef) { QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle); #ifdef Q_OS_MACX - return QDir::cleanPath(QString(path) + QLatin1String("/Contents/") + ret); + QString bundleContentsDir = QString(path) + QLatin1String("/Contents/"); + if (QDir(bundleContentsDir).exists()) + return QDir::cleanPath(bundleContentsDir + ret); #else return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS #endif -- cgit v1.2.3 From 687fbc11525fddda73ba4925d916be555df22ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 1 Apr 2014 14:54:24 +0200 Subject: Improve QWidget::metric for PdmDevicePixelRatio. Use QWindow::devicePixelRatio() which is the most accurate devicePixelRatio accessor since it can ask the platform native window directly Fall back to qApp->devicePixelRatio() if the window pointer is not valid. Task-number: QTBUG-37606 Task-number: QTBUG-38078 Change-Id: Ief1468a0c6ced07439f55329ab056883016241cc Reviewed-by: Gabriel de Dietrich --- src/widgets/kernel/qwidget_qpa.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 85ae55b8ac..c22320e8d2 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -834,13 +834,16 @@ int QWidget::metric(PaintDeviceMetric m) const { Q_D(const QWidget); + QWindow *topLevelWindow = 0; QScreen *screen = 0; if (QWidget *topLevel = window()) - if (QWindow *topLevelWindow = topLevel->windowHandle()) { - QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow); - if (platformScreen) - screen = platformScreen->screen(); - } + topLevelWindow = topLevel->windowHandle(); + + if (topLevelWindow) { + QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow); + if (platformScreen) + screen = platformScreen->screen(); + } if (!screen && QGuiApplication::primaryScreen()) screen = QGuiApplication::primaryScreen(); @@ -877,7 +880,7 @@ int QWidget::metric(PaintDeviceMetric m) const } else if (m == PdmPhysicalDpiY) { return qRound(screen->physicalDotsPerInchY()); } else if (m == PdmDevicePixelRatio) { - return screen->devicePixelRatio(); + return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio(); } else { val = QPaintDevice::metric(m);// XXX } -- cgit v1.2.3 From 0ebfd0866d7cc9e3dabccf088d8ef1339dfe51a6 Mon Sep 17 00:00:00 2001 From: Alejandro Exojo Date: Mon, 10 Mar 2014 11:40:26 +0100 Subject: Use category names when logging to the journal Use the custom field QT_CATEGORY to store the name of the QLoggingCategory used when writing to systemd's journal. To pass custom fields sd_journal_send() is needed, and is used in combination with #define SD_JOURNAL_SUPPRESS_LOCATION to store the metadata that is already in the QMessageLogContext. Change-Id: I6a120701f7012aaa46451dd3d91586a419c5f803 Reviewed-by: Kai Koehne Reviewed-by: Thiago Macieira Reviewed-by: Robin Burchell --- config.tests/unix/journald/journald.c | 8 +++++++- src/corelib/global/qlogging.cpp | 16 +++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/config.tests/unix/journald/journald.c b/config.tests/unix/journald/journald.c index 470d526e68..32f0de683b 100644 --- a/config.tests/unix/journald/journald.c +++ b/config.tests/unix/journald/journald.c @@ -40,9 +40,15 @@ ****************************************************************************/ #include +#include int main(int argc, char **argv) { - sd_journal_print_with_location(LOG_INFO, "CODE_FILE=foo.c", "CODE_LINE=0", "unknown_function", "test message"); + sd_journal_send("MESSAGE=%s", "test message", + "PRIORITY=%i", LOG_INFO, + "CODE_FUNC=%s", "unknown", + "CODE_LINE=%d", 0, + "CODE_FILE=%s", "foo.c", + NULL); return 0; } diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 8c1d8b867d..da26490d18 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -64,7 +64,9 @@ #endif #if defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED) +# define SD_JOURNAL_SUPPRESS_LOCATION # include +# include # include #endif @@ -1170,13 +1172,13 @@ static void systemd_default_message_handler(QtMsgType type, break; } - char filebuf[PATH_MAX + sizeof("CODE_FILE=")]; - snprintf(filebuf, sizeof(filebuf), "CODE_FILE=%s", context.file ? context.file : "unknown"); - - char linebuf[20]; - snprintf(linebuf, sizeof(linebuf), "CODE_LINE=%d", context.line); - - sd_journal_print_with_location(priority, filebuf, linebuf, context.function ? context.function : "unknown", "%s", message.toUtf8().constData()); + sd_journal_send("MESSAGE=%s", message.toUtf8().constData(), + "PRIORITY=%i", priority, + "CODE_FUNC=%s", context.function ? context.function : "unknown", + "CODE_LINE=%d", context.line, + "CODE_FILE=%s", context.file ? context.file : "unknown", + "QT_CATEGORY=%s", context.category ? context.category : "unknown", + NULL); } #endif -- cgit v1.2.3 From d84da399649d01ac689e87295f8decc024a4f8e8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 16 Aug 2012 17:15:33 +0200 Subject: Use the new 3-operand testAndSet functions in QMutex This allows us to get the current value of the QMutex / QBasicMutex after the testAndSet operation failed. It saves an extra load from memory. Change-Id: I4922a8b3df15e342b177b13f56cf4f1184314520 Reviewed-by: Marc Mutz --- src/corelib/thread/qmutex.cpp | 12 ++++++------ src/corelib/thread/qmutex.h | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 0f305b79af..fe5beb1c01 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -216,9 +216,9 @@ QMutex::~QMutex() */ void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT { - if (fastTryLock()) + QMutexData *current; + if (fastTryLock(current)) return; - QMutexData *current = d_ptr.loadAcquire(); if (QT_PREPEND_NAMESPACE(isRecursive)(current)) static_cast(current)->lock(-1); else @@ -250,9 +250,9 @@ void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT */ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT { - if (fastTryLock()) + QMutexData *current; + if (fastTryLock(current)) return true; - QMutexData *current = d_ptr.loadAcquire(); if (QT_PREPEND_NAMESPACE(isRecursive)(current)) return static_cast(current)->lock(timeout); else @@ -268,9 +268,9 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT */ void QMutex::unlock() Q_DECL_NOTHROW { - if (fastTryUnlock()) + QMutexData *current; + if (fastTryUnlock(current)) return; - QMutexData *current = d_ptr.loadAcquire(); if (QT_PREPEND_NAMESPACE(isRecursive)(current)) static_cast(current)->unlock(); else diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index 0bca0def22..0ecc96a9b1 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -86,6 +86,12 @@ private: inline bool fastTryUnlock() Q_DECL_NOTHROW { return d_ptr.testAndSetRelease(dummyLocked(), 0); } + inline bool fastTryLock(QMutexData *¤t) Q_DECL_NOTHROW { + return d_ptr.testAndSetAcquire(0, dummyLocked(), current); + } + inline bool fastTryUnlock(QMutexData *¤t) Q_DECL_NOTHROW { + return d_ptr.testAndSetRelease(dummyLocked(), 0, current); + } void lockInternal() QT_MUTEX_LOCK_NOEXCEPT; bool lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT; -- cgit v1.2.3 From bc46b591b2cb81a5cb0c513aa4139b7e88fa8b06 Mon Sep 17 00:00:00 2001 From: John Layt Date: Fri, 28 Mar 2014 10:58:25 +0100 Subject: QPagedPaintDevice - Move QPageLayout methods The new QPageLayout methods weren't originally added to QPagePaintDevice as no new virtuals can be added, instead static polymorphism was used to add the methods directly in the derived classes QPdfWriter and QPrinter. This however means that classes like QTextDocument with print() methods that take a QPagedPaintDevice are unable to access the QPageLayout methods. To fix this, instead make the QPagedPaintDevicePrivate a virtual class and have QPdfWriter and QPrinter implement derived private classes that are called by the non-virtual QPagedPaintDevice base methods. Change-Id: Ieb6e513b1fa05f5ae76ea1f9156b0b1a053089eb Reviewed-by: Lars Knoll --- src/gui/painting/qpagedpaintdevice.cpp | 146 ++++++++++++++++++++++++++++++ src/gui/painting/qpagedpaintdevice.h | 12 ++- src/gui/painting/qpagedpaintdevice_p.h | 42 ++++++++- src/gui/painting/qpdfwriter.cpp | 129 ++++++++++++++------------ src/gui/painting/qpdfwriter.h | 5 +- src/printsupport/kernel/qprinter.cpp | 160 +++++++++++++++++++-------------- src/printsupport/kernel/qprinter.h | 6 ++ 7 files changed, 374 insertions(+), 126 deletions(-) diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp index 18ba964a26..e102b7fae3 100644 --- a/src/gui/painting/qpagedpaintdevice.cpp +++ b/src/gui/painting/qpagedpaintdevice.cpp @@ -65,6 +65,15 @@ QPagedPaintDevice::QPagedPaintDevice() { } +/*! + \internal + Constructs a new paged paint device with the derived private class. +*/ +QPagedPaintDevice::QPagedPaintDevice(QPagedPaintDevicePrivate *dd) + : d(dd) +{ +} + /*! Destroys the object. */ @@ -73,6 +82,15 @@ QPagedPaintDevice::~QPagedPaintDevice() delete d; } +/*! + \internal + Returns the QPagedPaintDevicePrivate. +*/ +QPagedPaintDevicePrivate *QPagedPaintDevice::dd() +{ + return d; +} + /*! \enum QPagedPaintDevice::PageSize @@ -295,6 +313,134 @@ QPagedPaintDevice::Margins QPagedPaintDevice::margins() const return result; } +/*! + \since 5.3 + + Sets the page layout to \a newPageLayout. + + You should call this before calling QPainter::begin(), or immediately + before calling newPage() to apply the new page layout to a new page. + You should not call any painting methods between a call to setPageLayout() + and newPage() as the wrong paint metrics may be used. + + Returns true if the page layout was successfully set to \a newPageLayout. + + \sa pageLayout() +*/ + +bool QPagedPaintDevice::setPageLayout(const QPageLayout &newPageLayout) +{ + return d->setPageLayout(newPageLayout); +} + +/*! + \since 5.3 + + Sets the page size to \a pageSize. + + To get the current QPageSize use pageLayout().pageSize(). + + You should call this before calling QPainter::begin(), or immediately + before calling newPage() to apply the new page size to a new page. + You should not call any painting methods between a call to setPageSize() + and newPage() as the wrong paint metrics may be used. + + Returns true if the page size was successfully set to \a pageSize. + + \sa pageLayout() +*/ + +bool QPagedPaintDevice::setPageSize(const QPageSize &pageSize) +{ + return d->setPageSize(pageSize); +} + +/*! + \since 5.3 + + Sets the page \a orientation. + + The page orientation is used to define the orientation of the + page size when obtaining the page rect. + + You should call this before calling QPainter::begin(), or immediately + before calling newPage() to apply the new orientation to a new page. + You should not call any painting methods between a call to setPageOrientation() + and newPage() as the wrong paint metrics may be used. + + To get the current QPageLayout::Orientation use pageLayout().pageOrientation(). + + Returns true if the page orientation was successfully set to \a orientation. + + \sa pageLayout() +*/ + +bool QPagedPaintDevice::setPageOrientation(QPageLayout::Orientation orientation) +{ + return d->setPageOrientation(orientation); +} + +/*! + \since 5.3 + + Set the page \a margins in the current page layout units. + + You should call this before calling QPainter::begin(), or immediately + before calling newPage() to apply the new margins to a new page. + You should not call any painting methods between a call to setPageMargins() + and newPage() as the wrong paint metrics may be used. + + To get the current page margins use pageLayout().pageMargins(). + + Returns true if the page margins were successfully set to \a margins. + + \sa pageLayout() +*/ + +bool QPagedPaintDevice::setPageMargins(const QMarginsF &margins) +{ + return d->setPageMargins(margins); +} + +/*! + \since 5.3 + + Set the page \a margins defined in the given \a units. + + You should call this before calling QPainter::begin(), or immediately + before calling newPage() to apply the new margins to a new page. + You should not call any painting methods between a call to setPageMargins() + and newPage() as the wrong paint metrics may be used. + + To get the current page margins use pageLayout().pageMargins(). + + Returns true if the page margins were successfully set to \a margins. + + \sa pageLayout() +*/ + +bool QPagedPaintDevice::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) +{ + return d->setPageMargins(margins, units); +} + +/*! + \since 5.3 + + Returns the current page layout. Use this method to access the current + QPageSize, QPageLayout::Orientation, QMarginsF, fullRect() and paintRect(). + + Note that you cannot use the setters on the returned object, you must either + call the individual QPagedPaintDevice setters or use setPageLayout(). + + \sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins() +*/ + +QPageLayout QPagedPaintDevice::pageLayout() const +{ + return d->pageLayout(); +} + /*! \internal diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h index 6d4c422a95..dec56f9ce8 100644 --- a/src/gui/painting/qpagedpaintdevice.h +++ b/src/gui/painting/qpagedpaintdevice.h @@ -43,6 +43,7 @@ #define QPAGEDPAINTDEVICE_H #include +#include QT_BEGIN_NAMESPACE @@ -51,7 +52,6 @@ QT_BEGIN_NAMESPACE #endif class QPagedPaintDevicePrivate; -class QPageLayout; class Q_GUI_EXPORT QPagedPaintDevice : public QPaintDevice { @@ -214,6 +214,14 @@ public: Envelope10 = Comm10E }; + // ### Qt6 Make these virtual + bool setPageLayout(const QPageLayout &pageLayout); + bool setPageSize(const QPageSize &pageSize); + bool setPageOrientation(QPageLayout::Orientation orientation); + bool setPageMargins(const QMarginsF &margins); + bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units); + QPageLayout pageLayout() const; + virtual void setPageSize(PageSize size); PageSize pageSize() const; @@ -232,6 +240,8 @@ public: Margins margins() const; protected: + QPagedPaintDevice(QPagedPaintDevicePrivate *dd); + QPagedPaintDevicePrivate *dd(); QPageLayout devicePageLayout() const; QPageLayout &devicePageLayout(); friend class QPagedPaintDevicePrivate; diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h index da58951dc7..2321494779 100644 --- a/src/gui/painting/qpagedpaintdevice_p.h +++ b/src/gui/painting/qpagedpaintdevice_p.h @@ -55,8 +55,6 @@ #include -#include "qpagelayout.h" - QT_BEGIN_NAMESPACE class Q_GUI_EXPORT QPagedPaintDevicePrivate @@ -71,6 +69,46 @@ public: { } + virtual ~QPagedPaintDevicePrivate() + { + } + + // ### Qt6 Remove these and make public class methods virtual + virtual bool setPageLayout(const QPageLayout &newPageLayout) + { + m_pageLayout = newPageLayout; + return m_pageLayout.isEquivalentTo(newPageLayout);; + } + + virtual bool setPageSize(const QPageSize &pageSize) + { + m_pageLayout.setPageSize(pageSize); + return m_pageLayout.pageSize().isEquivalentTo(pageSize); + } + + virtual bool setPageOrientation(QPageLayout::Orientation orientation) + { + m_pageLayout.setOrientation(orientation); + return m_pageLayout.orientation() == orientation; + } + + virtual bool setPageMargins(const QMarginsF &margins) + { + return setPageMargins(margins, m_pageLayout.units()); + } + + virtual bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) + { + m_pageLayout.setUnits(units); + m_pageLayout.setMargins(margins); + return m_pageLayout.margins() == margins && m_pageLayout.units() == units; + } + + virtual QPageLayout pageLayout() const + { + return m_pageLayout; + } + static inline QPagedPaintDevicePrivate *get(QPagedPaintDevice *pd) { return pd->d; } QPageLayout m_pageLayout; diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp index 08c8f42fd9..b856d6625c 100644 --- a/src/gui/painting/qpdfwriter.cpp +++ b/src/gui/painting/qpdfwriter.cpp @@ -43,6 +43,7 @@ #ifndef QT_NO_PDF +#include "qpagedpaintdevice_p.h" #include #include "private/qpdf_p.h" #include @@ -68,6 +69,64 @@ public: QFile *output; }; +class QPdfPagedPaintDevicePrivate : public QPagedPaintDevicePrivate +{ +public: + QPdfPagedPaintDevicePrivate(QPdfWriterPrivate *d) + : QPagedPaintDevicePrivate(), pd(d) + {} + + virtual ~QPdfPagedPaintDevicePrivate() + {} + + bool setPageLayout(const QPageLayout &newPageLayout) Q_DECL_OVERRIDE + { + // Try to set the paint engine page layout + pd->engine->setPageLayout(newPageLayout); + // Set QPagedPaintDevice layout to match the current paint engine layout + m_pageLayout = pd->engine->pageLayout(); + return m_pageLayout.isEquivalentTo(newPageLayout); + } + + bool setPageSize(const QPageSize &pageSize) Q_DECL_OVERRIDE + { + // Try to set the paint engine page size + pd->engine->setPageSize(pageSize); + // Set QPagedPaintDevice layout to match the current paint engine layout + m_pageLayout = pd->engine->pageLayout(); + return m_pageLayout.pageSize().isEquivalentTo(pageSize); + } + + bool setPageOrientation(QPageLayout::Orientation orientation) Q_DECL_OVERRIDE + { + // Set the print engine value + pd->engine->setPageOrientation(orientation); + // Set QPagedPaintDevice layout to match the current paint engine layout + m_pageLayout = pd->engine->pageLayout(); + return m_pageLayout.orientation() == orientation; + } + + bool setPageMargins(const QMarginsF &margins) Q_DECL_OVERRIDE + { + return setPageMargins(margins, pageLayout().units()); + } + + bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) Q_DECL_OVERRIDE + { + // Try to set engine margins + pd->engine->setPageMargins(margins, units); + // Set QPagedPaintDevice layout to match the current paint engine layout + m_pageLayout = pd->engine->pageLayout(); + return m_pageLayout.margins() == margins && m_pageLayout.units() == units; + } + + QPageLayout pageLayout() const Q_DECL_OVERRIDE + { + return pd->engine->pageLayout(); + } + + QPdfWriterPrivate *pd; +}; /*! \class QPdfWriter \inmodule QtGui @@ -85,7 +144,8 @@ public: Constructs a PDF writer that will write the pdf to \a filename. */ QPdfWriter::QPdfWriter(const QString &filename) - : QObject(*new QPdfWriterPrivate) + : QObject(*new QPdfWriterPrivate), + QPagedPaintDevice(new QPdfPagedPaintDevicePrivate(d_func())) { Q_D(QPdfWriter); @@ -195,7 +255,10 @@ int QPdfWriter::resolution() const return d->engine->resolution(); } +// Defined in QPagedPaintDevice but non-virtual, add QPdfWriter specific doc here +#ifdef Q_QDOC /*! + \fn bool QPdfWriter::setPageLayout(const QPageLayout &newPageLayout) \since 5.3 Sets the PDF page layout to \a newPageLayout. @@ -210,17 +273,8 @@ int QPdfWriter::resolution() const \sa pageLayout() */ -bool QPdfWriter::setPageLayout(const QPageLayout &newPageLayout) -{ - Q_D(const QPdfWriter); - // Try to set the paint engine page layout - d->engine->setPageLayout(newPageLayout); - // Set QPagedPaintDevice layout to match the current paint engine layout - devicePageLayout() = d->engine->pageLayout(); - return pageLayout().isEquivalentTo(newPageLayout); -} - /*! + \fn bool QPdfWriter::setPageSize(const QPageSize &pageSize) \since 5.3 Sets the PDF page size to \a pageSize. @@ -237,17 +291,8 @@ bool QPdfWriter::setPageLayout(const QPageLayout &newPageLayout) \sa pageLayout() */ -bool QPdfWriter::setPageSize(const QPageSize &pageSize) -{ - Q_D(const QPdfWriter); - // Try to set the paint engine page size - d->engine->setPageSize(pageSize); - // Set QPagedPaintDevice layout to match the current paint engine layout - devicePageLayout() = d->engine->pageLayout(); - return pageLayout().pageSize().isEquivalentTo(pageSize); -} - /*! + \fn bool QPdfWriter::setPageOrientation(QPageLayout::Orientation orientation) \since 5.3 Sets the PDF page \a orientation. @@ -267,17 +312,8 @@ bool QPdfWriter::setPageSize(const QPageSize &pageSize) \sa pageLayout() */ -bool QPdfWriter::setPageOrientation(QPageLayout::Orientation orientation) -{ - Q_D(const QPdfWriter); - // Set the print engine value - d->engine->setPageOrientation(orientation); - // Set QPagedPaintDevice layout to match the current paint engine layout - devicePageLayout() = d->engine->pageLayout(); - return pageLayout().orientation() == orientation; -} - /*! + \fn bool QPdfWriter::setPageMargins(const QMarginsF &margins) \since 5.3 Set the PDF page \a margins in the current page layout units. @@ -294,17 +330,8 @@ bool QPdfWriter::setPageOrientation(QPageLayout::Orientation orientation) \sa pageLayout() */ -bool QPdfWriter::setPageMargins(const QMarginsF &margins) -{ - Q_D(const QPdfWriter); - // Try to set engine margins - d->engine->setPageMargins(margins, pageLayout().units()); - // Set QPagedPaintDevice layout to match the current paint engine layout - devicePageLayout() = d->engine->pageLayout(); - return pageLayout().margins() == margins; -} - /*! + \fn bool QPdfWriter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) \since 5.3 Set the PDF page \a margins defined in the given \a units. @@ -321,17 +348,10 @@ bool QPdfWriter::setPageMargins(const QMarginsF &margins) \sa pageLayout() */ -bool QPdfWriter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) -{ - Q_D(const QPdfWriter); - // Try to set engine margins - d->engine->setPageMargins(margins, units); - // Set QPagedPaintDevice layout to match the current paint engine layout - devicePageLayout() = d->engine->pageLayout(); - return pageLayout().margins() == margins && pageLayout().units() == units; -} - /*! + \fn QPageLayout QPdfWriter::pageLayout() const + \since 5.3 + Returns the current page layout. Use this method to access the current QPageSize, QPageLayout::Orientation, QMarginsF, fullRect() and paintRect(). @@ -340,12 +360,7 @@ bool QPdfWriter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit unit \sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins() */ - -QPageLayout QPdfWriter::pageLayout() const -{ - Q_D(const QPdfWriter); - return d->engine->pageLayout(); -} +#endif /*! \reimp diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h index fce0b88ea8..747ce380e7 100644 --- a/src/gui/painting/qpdfwriter.h +++ b/src/gui/painting/qpdfwriter.h @@ -74,13 +74,16 @@ public: void setResolution(int resolution); int resolution() const; +#ifdef Q_QDOC bool setPageLayout(const QPageLayout &pageLayout); bool setPageSize(const QPageSize &pageSize); bool setPageOrientation(QPageLayout::Orientation orientation); bool setPageMargins(const QMarginsF &margins); bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units); - QPageLayout pageLayout() const; +#else + using QPagedPaintDevice::setPageSize; +#endif void setPageSize(PageSize size); void setPageSizeMM(const QSizeF &size); diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 153fb23d36..bdc9a98f2e 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -220,6 +220,87 @@ void QPrinterPrivate::setProperty(QPrintEngine::PrintEnginePropertyKey key, cons } +class QPrinterPagedPaintDevicePrivate : public QPagedPaintDevicePrivate +{ +public: + QPrinterPagedPaintDevicePrivate(QPrinterPrivate *d) + : QPagedPaintDevicePrivate(), pd(d) + {} + + virtual ~QPrinterPagedPaintDevicePrivate() + {} + + bool setPageLayout(const QPageLayout &newPageLayout) Q_DECL_OVERRIDE + { + if (pd->paintEngine->type() != QPaintEngine::Pdf + && pd->printEngine->printerState() == QPrinter::Active) { + qWarning("QPrinter::setPageLayout: Cannot be changed while printer is active"); + return false; + } + + // Try to set the print engine page layout + pd->setProperty(QPrintEngine::PPK_QPageLayout, QVariant::fromValue(newPageLayout)); + + // Set QPagedPaintDevice layout to match the current print engine value + m_pageLayout = pageLayout(); + + return pageLayout().isEquivalentTo(newPageLayout); + } + + bool setPageSize(const QPageSize &pageSize) Q_DECL_OVERRIDE + { + if (pd->paintEngine->type() != QPaintEngine::Pdf + && pd->printEngine->printerState() == QPrinter::Active) { + qWarning("QPrinter::setPageLayout: Cannot be changed while printer is active"); + return false; + } + + + // Try to set the print engine page size + pd->setProperty(QPrintEngine::PPK_QPageSize, QVariant::fromValue(pageSize)); + + // Set QPagedPaintDevice layout to match the current print engine value + m_pageLayout = pageLayout(); + + return pageLayout().pageSize().isEquivalentTo(pageSize); + } + + bool setPageOrientation(QPageLayout::Orientation orientation) Q_DECL_OVERRIDE + { + // Set the print engine value + pd->setProperty(QPrintEngine::PPK_Orientation, orientation); + + // Set QPagedPaintDevice layout to match the current print engine value + m_pageLayout = pageLayout(); + + return pageLayout().orientation() == orientation; + } + + bool setPageMargins(const QMarginsF &margins) Q_DECL_OVERRIDE + { + return setPageMargins(margins, pageLayout().units()); + } + + bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) Q_DECL_OVERRIDE + { + // Try to set print engine margins + QPair pair = qMakePair(margins, units); + pd->setProperty(QPrintEngine::PPK_QPageMargins, QVariant::fromValue(pair)); + + // Set QPagedPaintDevice layout to match the current print engine value + m_pageLayout = pageLayout(); + + return pageLayout().margins() == margins && pageLayout().units() == units; + } + + QPageLayout pageLayout() const Q_DECL_OVERRIDE + { + return pd->printEngine->property(QPrintEngine::PPK_QPageLayout).value(); + } + + QPrinterPrivate *pd; +}; + /*! \class QPrinter @@ -601,6 +682,8 @@ QPrinter::QPrinter(PrinterMode mode) : QPagedPaintDevice(), d_ptr(new QPrinterPrivate(this)) { + delete d; + d = new QPrinterPagedPaintDevicePrivate(d_func()); d_ptr->init(QPrinterInfo(), mode); } @@ -613,6 +696,8 @@ QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode) : QPagedPaintDevice(), d_ptr(new QPrinterPrivate(this)) { + delete d; + d = new QPrinterPagedPaintDevicePrivate(d_func()); d_ptr->init(printer, mode); } @@ -947,7 +1032,10 @@ void QPrinter::setCreator(const QString &creator) d->setProperty(QPrintEngine::PPK_Creator, creator); } +// Defined in QPagedPaintDevice but non-virtual, add QPrinter specific doc here +#ifdef Q_QDOC /*! + \fn bool QPrinter::setPageLayout(const QPageLayout &newLayout) \since 5.3 Sets the page layout to \a newLayout. @@ -961,23 +1049,8 @@ void QPrinter::setCreator(const QString &creator) \sa pageLayout(), setPageSize(), setPageOrientation(), setPageMargins() */ -bool QPrinter::setPageLayout(const QPageLayout &newLayout) -{ - Q_D(QPrinter); - - if (d->paintEngine->type() != QPaintEngine::Pdf) - ABORT_IF_ACTIVE_RETURN("QPrinter::setPageLayout", false); - - // Try to set the print engine page layout - d->setProperty(QPrintEngine::PPK_QPageLayout, QVariant::fromValue(newLayout)); - - // Set QPagedPaintDevice layout to match the current print engine value - devicePageLayout() = pageLayout(); - - return pageLayout().isEquivalentTo(newLayout); -} - /*! + \fn bool QPrinter::setPageSize(const QPageSize &pageSize) \since 5.3 Sets the page size to \a pageSize. @@ -995,23 +1068,8 @@ bool QPrinter::setPageLayout(const QPageLayout &newLayout) \sa pageLayout(), setPageLayout() */ -bool QPrinter::setPageSize(const QPageSize &pageSize) -{ - Q_D(QPrinter); - - if (d->paintEngine->type() != QPaintEngine::Pdf) - ABORT_IF_ACTIVE_RETURN("QPrinter::setPageSize", false); - - // Try to set the print engine page size - d->setProperty(QPrintEngine::PPK_QPageSize, QVariant::fromValue(pageSize)); - - // Set QPagedPaintDevice layout to match the current print engine value - devicePageLayout() = pageLayout(); - - return pageLayout().pageSize().isEquivalentTo(pageSize); -} - /*! + \fn bool QPrinter::setPageOrientation(QPageLayout::Orientation orientation) \since 5.3 Sets the page \a orientation to QPageLayout::Portrait or QPageLayout::Landscape. @@ -1029,20 +1087,8 @@ bool QPrinter::setPageSize(const QPageSize &pageSize) \sa pageLayout(), setPageLayout() */ -bool QPrinter::setPageOrientation(QPageLayout::Orientation orientation) -{ - Q_D(QPrinter); - - // Set the print engine value - d->setProperty(QPrintEngine::PPK_Orientation, orientation); - - // Set QPagedPaintDevice layout to match the current print engine value - devicePageLayout() = pageLayout(); - - return pageLayout().orientation() == orientation; -} - /*! + \fn bool QPrinter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) \since 5.3 Set the page margins to \a margins in the given \a units. If \a units are @@ -1059,21 +1105,10 @@ bool QPrinter::setPageOrientation(QPageLayout::Orientation orientation) \sa pageLayout(), setPageLayout() */ -bool QPrinter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) -{ - Q_D(QPrinter); - - // Try to set print engine margins - QPair pair = qMakePair(margins, units); - d->setProperty(QPrintEngine::PPK_QPageMargins, QVariant::fromValue(pair)); - - // Set QPagedPaintDevice layout to match the current print engine value - devicePageLayout() = pageLayout(); - - return pageLayout().margins() == margins && pageLayout().units() == units; -} - /*! + \fn QPageLayout QPrinter::pageLayout() const + \since 5.3 + Returns the current page layout. Use this method to access the current QPageSize, QPageLayout::Orientation, QMarginsF, fullPageRect() and paintRect(). @@ -1082,12 +1117,7 @@ bool QPrinter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) \sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins() */ - -QPageLayout QPrinter::pageLayout() const -{ - Q_D(const QPrinter); - return d->printEngine->property(QPrintEngine::PPK_QPageLayout).value(); -} +#endif /*! \obsolete Use pageLayout().pageOrientation() instead. diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h index 1f0639d81f..fa102d0fe3 100644 --- a/src/printsupport/kernel/qprinter.h +++ b/src/printsupport/kernel/qprinter.h @@ -307,11 +307,17 @@ public: void setCreator(const QString &); QString creator() const; +#ifdef Q_QDOC bool setPageLayout(const QPageLayout &pageLayout); bool setPageSize(const QPageSize &pageSize); bool setPageOrientation(QPageLayout::Orientation orientation); + bool setPageMargins(const QMarginsF &margins); bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units); QPageLayout pageLayout() const; +#else + using QPagedPaintDevice::setPageSize; + using QPagedPaintDevice::setPageMargins; +#endif void setOrientation(Orientation); Orientation orientation() const; -- cgit v1.2.3 From 39c5098dbb3dd547c315c5baf0f83ebe81b28756 Mon Sep 17 00:00:00 2001 From: John Layt Date: Mon, 24 Mar 2014 18:53:06 +0100 Subject: QPrintDialog - Add Direct print to manual test Enable printing without dialog. Change-Id: I1058361febc7ddd8a5e0471e4365969e2f8becfe Reviewed-by: Friedemann Kleint --- tests/manual/dialogs/printdialogpanel.cpp | 8 ++++++++ tests/manual/dialogs/printdialogpanel.h | 1 + tests/manual/dialogs/printdialogpanel.ui | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/tests/manual/dialogs/printdialogpanel.cpp b/tests/manual/dialogs/printdialogpanel.cpp index f7d027020c..1a18f94406 100644 --- a/tests/manual/dialogs/printdialogpanel.cpp +++ b/tests/manual/dialogs/printdialogpanel.cpp @@ -379,6 +379,7 @@ PrintDialogPanel::PrintDialogPanel(QWidget *parent) connect(m_panel.m_printButton, SIGNAL(clicked()), this, SLOT(showPrintDialog())); connect(m_panel.m_printPreviewButton, SIGNAL(clicked()), this, SLOT(showPreviewDialog())); connect(m_panel.m_pageSetupButton, SIGNAL(clicked()), this, SLOT(showPageSetupDialog())); + connect(m_panel.m_directPrintButton, SIGNAL(clicked()), this, SLOT(directPrint())); enablePanels(); m_blockSignals = false; @@ -686,6 +687,13 @@ void PrintDialogPanel::showPageSetupDialog() retrieveSettings(m_printer.data()); } +void PrintDialogPanel::directPrint() +{ + applySettings(m_printer.data()); + print(m_printer.data()); + retrieveSettings(m_printer.data()); +} + #include "moc_printdialogpanel.cpp" #include "printdialogpanel.moc" diff --git a/tests/manual/dialogs/printdialogpanel.h b/tests/manual/dialogs/printdialogpanel.h index 3932cd174f..3d340c7ccc 100644 --- a/tests/manual/dialogs/printdialogpanel.h +++ b/tests/manual/dialogs/printdialogpanel.h @@ -101,6 +101,7 @@ private slots: void showPrintDialog(); void showPreviewDialog(); void showPageSetupDialog(); + void directPrint(); void unitsChanged(); void pageSizeChanged(); void pageDimensionsChanged(); diff --git a/tests/manual/dialogs/printdialogpanel.ui b/tests/manual/dialogs/printdialogpanel.ui index 733d52ad9e..2f0fe606a3 100644 --- a/tests/manual/dialogs/printdialogpanel.ui +++ b/tests/manual/dialogs/printdialogpanel.ui @@ -644,6 +644,13 @@ + + + + Direct Print + + + -- cgit v1.2.3 From cc57a2e90f18a39ce3c74b6ad0db9a64aa135ddf Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 2 Apr 2014 19:49:08 +0200 Subject: Accessibility text updates for QTextEdit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For Mac this makes QTextEdit work nicely with VoiceOver. Task-number: QTBUG-37204 Change-Id: I1326d24ca6a932ad667ee395f62881b6ec64e892 Reviewed-by: Jan Arve Sæther --- src/widgets/widgets/qwidgettextcontrol.cpp | 28 +++++++++++++++ src/widgets/widgets/qwidgettextcontrol_p.h | 1 + src/widgets/widgets/qwidgettextcontrol_p_p.h | 1 + .../other/qaccessibility/tst_qaccessibility.cpp | 42 ++++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 3740f3e698..9cc62fd10a 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -438,6 +438,7 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection())); QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor))); + QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, SLOT(_q_contentsChanged(int,int,int))); QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged())); // convenience signal forwards @@ -641,6 +642,33 @@ void QWidgetTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someC } } +void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, int charsAdded) +{ + Q_Q(QWidgetTextControl); +#ifndef QT_NO_ACCESSIBILITY + if (QAccessible::isActive()) { + QTextCursor tmp(doc); + tmp.setPosition(from); + tmp.setPosition(from + charsAdded, QTextCursor::KeepAnchor); + QString newText = tmp.selectedText(); + + // always report the right number of removed chars, but in lack of the real string use spaces + QString oldText = QString(charsRemoved, QLatin1Char(' ')); + + QAccessibleEvent *ev = 0; + if (charsRemoved == 0) { + ev = new QAccessibleTextInsertEvent(q->parent(), from, newText); + } else if (charsAdded == 0) { + ev = new QAccessibleTextRemoveEvent(q->parent(), from, oldText); + } else { + ev = new QAccessibleTextUpdateEvent(q->parent(), from, oldText, newText); + } + QAccessible::updateAccessibility(ev); + delete ev; + } +#endif +} + void QWidgetTextControlPrivate::_q_documentLayoutChanged() { Q_Q(QWidgetTextControl); diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h index 0c76355ca1..867b55fe32 100644 --- a/src/widgets/widgets/qwidgettextcontrol_p.h +++ b/src/widgets/widgets/qwidgettextcontrol_p.h @@ -262,6 +262,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_copyLink()) Q_PRIVATE_SLOT(d_func(), void _q_updateBlock(const QTextBlock &)) Q_PRIVATE_SLOT(d_func(), void _q_documentLayoutChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_contentsChanged(int, int, int)) }; diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h index 727821015e..4d578c76f8 100644 --- a/src/widgets/widgets/qwidgettextcontrol_p_p.h +++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h @@ -111,6 +111,7 @@ public: #endif void _q_emitCursorPosChanged(const QTextCursor &someCursor); + void _q_contentsChanged(int from, int charsRemoved, int charsAdded); void setBlinkingCursorEnabled(bool enable); diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 9f0540173a..fcc5581bea 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -1711,6 +1711,48 @@ void tst_QAccessibility::textEditTest() QCOMPARE(textIface->textAtOffset(28, QAccessible::CharBoundary, &start, &end), QLatin1String("\n")); QCOMPARE(start, 28); QCOMPARE(end, 29); + + edit.clear(); + QTestAccessibility::clearEvents(); + + // make sure we get notifications when typing text + QTestEventList keys; + keys.addKeyClick('A'); + keys.simulate(&edit); + keys.clear(); + QAccessibleTextInsertEvent insertA(&edit, 0, "A"); + QVERIFY_EVENT(&insertA); + QAccessibleTextCursorEvent move1(&edit, 1); + QVERIFY_EVENT(&move1); + + + keys.addKeyClick('c'); + keys.simulate(&edit); + keys.clear(); + QAccessibleTextInsertEvent insertC(&edit, 1, "c"); + QVERIFY_EVENT(&insertC); + QAccessibleTextCursorEvent move2(&edit, 2); + QVERIFY_EVENT(&move2); + + keys.addKeyClick(Qt::Key_Backspace); + keys.simulate(&edit); + keys.clear(); + + // FIXME this should get a proper string instead of space + QAccessibleTextRemoveEvent del(&edit, 1, " "); + QVERIFY_EVENT(&del); + QVERIFY_EVENT(&move1); + + // it would be nicer to get a text update event, but the current implementation + // instead does remove and insert which is also fine + edit.setText(QStringLiteral("Accessibility rocks")); + QAccessibleTextRemoveEvent remove(&edit, 0, " "); + QVERIFY_EVENT(&remove); + + // FIXME the new text is not there yet + QEXPECT_FAIL("", "Inserting should always contain the new text", Continue); + QAccessibleTextInsertEvent insert(&edit, 0, "Accessibility rocks"); + QVERIFY_EVENT(&insert); } QTestAccessibility::clearEvents(); } -- cgit v1.2.3 From a7f98a7ac01a9faa08d1119cf4d5550c50e00005 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Fri, 28 Mar 2014 10:43:32 +0100 Subject: Mac Accessibility: Make more widgets name/description work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0abe17a59f95818939d6b82500d2463c3f135989 Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 0b674b8d2f..d9bfdbd55d 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -116,6 +116,7 @@ NSAccessibilityTopLevelUIElementAttribute, NSAccessibilityPositionAttribute, NSAccessibilitySizeAttribute, + NSAccessibilityTitleAttribute, NSAccessibilityDescriptionAttribute, NSAccessibilityEnabledAttribute, nil]; @@ -176,8 +177,10 @@ } else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) { QSize qtSize = iface->rect().size(); return [NSValue valueWithSize: NSMakeSize(qtSize.width(), qtSize.height())]; - } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) { + } else if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) { return QCFString::toNSString(iface->text(QAccessible::Name)); + } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) { + return QCFString::toNSString(iface->text(QAccessible::Description)); } else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) { return [NSNumber numberWithBool:!iface->state().disabled]; } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { -- cgit v1.2.3 From b5eb850e0deb61ff71e26a5a2d0e070b91306aa2 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 31 Mar 2014 14:17:29 +0200 Subject: OSX: add several menuitem roles to support menu shortcuts in dialogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now menu items and key shortcuts for Cut, Copy, Paste and Select All work in the standard ways in dialogs such as the file dialog, provided that the corresponding QActions have been created and added to the menu. This depends on new roles to identify each menu item which is so broadly applicable that it should work even when a native widget has focus; but the role will be auto-detected, just as we were already doing for application menu items such as Quit, About and Preferences. When the QFileDialog is opened, it will call redirectKnownMenuItemsToFirstResponder() which will make only those "special" menu items have the standard actions and nil targets. When the dialog is dismissed, those NSMenuItems must be reverted by calling resetKnownMenuItemsToQt(), because to invoke a QAction, the NSMenuItem's action should be itemFired and the target should be the QCocoaMenuDelegate. Task-number: QTBUG-17291 Change-Id: I501375ca6fa13fac75d4b4fdcede993ec2329cc7 Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qplatformmenu.h | 6 ++- src/plugins/platforms/cocoa/messages.cpp | 8 +++ .../platforms/cocoa/qcocoafiledialoghelper.mm | 6 +++ src/plugins/platforms/cocoa/qcocoamenubar.h | 4 ++ src/plugins/platforms/cocoa/qcocoamenubar.mm | 63 ++++++++++++++++++++++ src/plugins/platforms/cocoa/qcocoamenuitem.h | 3 ++ src/plugins/platforms/cocoa/qcocoamenuitem.mm | 15 +++++- tests/manual/dialogs/main.cpp | 9 ++++ 8 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index 9326a2b3a1..19e2d9bccf 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -66,7 +66,11 @@ Q_OBJECT public: // copied from, and must stay in sync with, QAction menu roles. enum MenuRole { NoRole = 0, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole, - AboutRole, PreferencesRole, QuitRole }; + AboutRole, PreferencesRole, QuitRole, + // However these roles are private, perhaps temporarily. + // They could be added as public QAction roles if necessary. + CutRole, CopyRole, PasteRole, SelectAllRole, + RoleCount }; virtual void setTag(quintptr tag) = 0; virtual quintptr tag()const = 0; diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp index 1fe80b28b1..8fc8b312f5 100644 --- a/src/plugins/platforms/cocoa/messages.cpp +++ b/src/plugins/platforms/cocoa/messages.cpp @@ -90,6 +90,14 @@ QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption) || caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Exit"), Qt::CaseInsensitive)) { return QPlatformMenuItem::QuitRole; } + if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Cut"), Qt::CaseInsensitive)) + return QPlatformMenuItem::CutRole; + if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Copy"), Qt::CaseInsensitive)) + return QPlatformMenuItem::CopyRole; + if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Paste"), Qt::CaseInsensitive)) + return QPlatformMenuItem::PasteRole; + if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Select All"), Qt::CaseInsensitive)) + return QPlatformMenuItem::SelectAllRole; return QPlatformMenuItem::NoRole; } diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 8728ab8764..2b7b8109ad 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -52,6 +52,7 @@ #include #include "qt_mac_p.h" #include "qcocoahelpers.h" +#include "qcocoamenubar.h" #include #include #include @@ -225,6 +226,7 @@ static QString strippedText(QString s) || [self panel:nil shouldShowFilename:filepath]; [self updateProperties]; + QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); [mOpenPanel setAllowedFileTypes:nil]; [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""]; @@ -250,7 +252,9 @@ static QString strippedText(QString s) // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will // close down during the cleanup. qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); + QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); mReturnCode = [mSavePanel runModal]; + QCocoaMenuBar::resetKnownMenuItemsToQt(); QAbstractEventDispatcher::instance()->interrupt(); return (mReturnCode == NSOKButton); @@ -269,6 +273,7 @@ static QString strippedText(QString s) || [self panel:nil shouldShowFilename:filepath]; [self updateProperties]; + QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); [mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]]; [mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""]; @@ -583,6 +588,7 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_selectionChanged(const QSt void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted) { + QCocoaMenuBar::resetKnownMenuItemsToQt(); if (accepted) { emit accept(); } else { diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index 7a1bda74a4..fa02a7870b 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -67,9 +67,13 @@ public: inline NSMenu *nsMenu() const { return m_nativeMenu; } + static void redirectKnownMenuItemsToFirstResponder(); + static void resetKnownMenuItemsToQt(); static void updateMenuBarImmediately(); QList merged() const; + NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r); + private: static QCocoaWindow *findWindowForMenubar(); static QCocoaMenuBar *findGlobalMenubar(); diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 7335deb800..ffc0fabdce 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -205,6 +205,59 @@ QCocoaMenuBar *QCocoaMenuBar::findGlobalMenubar() return NULL; } +void QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder() +{ + // QTBUG-17291: http://forums.macrumors.com/showthread.php?t=1249452 + // When a dialog is opened, shortcuts for actions inside the dialog (cut, paste, ...) + // continue to go through the same menu items which claimed those shortcuts. + // They are not keystrokes which we can intercept in any other way; the OS intercepts them. + // The menu items had to be created by the application. That's why we need roles + // to identify those "special" menu items which can be useful even when non-Qt + // native widgets are in focus. When the native widget is focused it will be the + // first responder, so the menu item needs to have its target be the first responder; + // this is done by setting it to nil. + + // This function will find all menu items on all menus which have + // "special" roles, set the target and also set the standard actions which + // apply to those roles. But afterwards it is necessary to call + // resetKnownMenuItemsToQt() to put back the target and action so that + // those menu items will go back to invoking their associated QActions. + foreach (QCocoaMenuBar *mb, static_menubars) + foreach (QCocoaMenu *m, mb->m_menus) + foreach (QCocoaMenuItem *i, m->items()) { + bool known = true; + switch (i->effectiveRole()) { + case QPlatformMenuItem::CutRole: + [i->nsItem() setAction:@selector(cut:)]; + break; + case QPlatformMenuItem::CopyRole: + [i->nsItem() setAction:@selector(copy:)]; + break; + case QPlatformMenuItem::PasteRole: + [i->nsItem() setAction:@selector(paste:)]; + break; + case QPlatformMenuItem::SelectAllRole: + [i->nsItem() setAction:@selector(selectAll:)]; + break; + // We may discover later that there are other roles/actions which + // are meaningful to standard native widgets; they can be added. + default: + known = false; + break; + } + if (known) + [i->nsItem() setTarget:nil]; + } +} + +void QCocoaMenuBar::resetKnownMenuItemsToQt() +{ + // Undo the effect of redirectKnownMenuItemsToFirstResponder(): + // set the menu items' actions to itemFired and their targets to + // the QCocoaMenuDelegate. + updateMenuBarImmediately(); +} + void QCocoaMenuBar::updateMenuBarImmediately() { QCocoaAutoReleasePool pool; @@ -321,3 +374,13 @@ QPlatformMenu *QCocoaMenuBar::menuForTag(quintptr tag) const return 0; } + +NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r) +{ + foreach (QCocoaMenu *m, m_menus) + foreach (QCocoaMenuItem *i, m->items()) + if (i->effectiveRole() == r) + return i->nsItem(); + return Q_NULLPTR; +} + diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index b0169b9746..61706c19bc 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -98,6 +98,8 @@ public: inline bool isSeparator() const { return m_isSeparator; } QCocoaMenu *menu() const { return m_menu; } + MenuRole effectiveRole() const; + private: QString mergeText(); QKeySequence mergeAccel(); @@ -112,6 +114,7 @@ private: bool m_isSeparator; QFont m_font; MenuRole m_role; + MenuRole m_detectedRole; QKeySequence m_shortcut; bool m_checked; bool m_merged; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 2246d2ce46..58fe07bc62 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -227,7 +227,8 @@ NSMenuItem *QCocoaMenuItem::sync() if (depth == 3 || !menubar) break; // Menu item too deep in the hierarchy, or not connected to any menubar - switch (detectMenuRole(m_text)) { + m_detectedRole = detectMenuRole(m_text); + switch (m_detectedRole) { case QPlatformMenuItem::AboutRole: if (m_text.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) mergeItem = [loader aboutMenuItem]; @@ -241,6 +242,8 @@ NSMenuItem *QCocoaMenuItem::sync() mergeItem = [loader quitMenuItem]; break; default: + if (m_detectedRole >= CutRole && m_detectedRole < RoleCount && menubar) + mergeItem = menubar->itemForRole(m_detectedRole); if (!m_text.isEmpty()) m_textSynced = true; break; @@ -249,7 +252,7 @@ NSMenuItem *QCocoaMenuItem::sync() } default: - qWarning() << Q_FUNC_INFO << "unsupported role" << (int) m_role; + qWarning() << Q_FUNC_INFO << "menu item" << m_text << "has unsupported role" << (int)m_role; } if (mergeItem) { @@ -374,3 +377,11 @@ void QCocoaMenuItem::syncModalState(bool modal) else [m_native setEnabled:m_enabled]; } + +QPlatformMenuItem::MenuRole QCocoaMenuItem::effectiveRole() const +{ + if (m_role > TextHeuristicRole) + return m_role; + else + return m_detectedRole; +} diff --git a/tests/manual/dialogs/main.cpp b/tests/manual/dialogs/main.cpp index 6082727c3b..b2b5007662 100644 --- a/tests/manual/dialogs/main.cpp +++ b/tests/manual/dialogs/main.cpp @@ -70,6 +70,15 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) QAction *quitAction = fileMenu->addAction(tr("Quit")); quitAction->setShortcut(QKeySequence(QKeySequence::Quit)); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QAction *action = editMenu->addAction(tr("Cut")); + action->setShortcut(QKeySequence(QKeySequence::Quit)); + action = editMenu->addAction(tr("Copy")); + action->setShortcut(QKeySequence(QKeySequence::Copy)); + action = editMenu->addAction(tr("Paste")); + action->setShortcut(QKeySequence(QKeySequence::Paste)); + action = editMenu->addAction(tr("Select All")); + action->setShortcut(QKeySequence(QKeySequence::SelectAll)); QTabWidget *tabWidget = new QTabWidget; tabWidget->addTab(new FileDialogPanel, tr("QFileDialog")); tabWidget->addTab(new ColorDialogPanel, tr("QColorDialog")); -- cgit v1.2.3 From f4f1f597d44d765a59f16a63e8c2e7d3bfeb2ea1 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Fri, 4 Apr 2014 18:28:20 +0200 Subject: Fix a crash on startup with QOpenGLWidget After c4aabeb2b82d777bb555f836f55e1f7ae4fb4581 we now try to access q_ptr in QWidgetPrivate::setRenderToTexture. QOpenGLWidget needs to delay this call after the QObject constructor is done to make sure that setTextureChildSeen doesn't dereference q_ptr before it has been initialized. Change-Id: Icaee82c8b806f42bc7614b0ac6fe4e6026331750 Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qopenglwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 8b0d7d525a..d9bc2f7bbd 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -60,7 +60,6 @@ public: QOpenGLWidgetPrivate() : fbo(0), uninitialized(true) { - setRenderToTexture(); } GLuint textureId() const { return fbo ? fbo->texture() : 0; } @@ -91,6 +90,8 @@ void QOpenGLWidgetPrivate::initialize() QOpenGLWidget::QOpenGLWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(*(new QOpenGLWidgetPrivate), parent, f) { + Q_D(QOpenGLWidget); + d->setRenderToTexture(); } QOpenGLWidget::~QOpenGLWidget() -- cgit v1.2.3 From e30ae1268f8e224369ff7841b90184c8694a86e7 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 7 Apr 2014 10:42:48 +0200 Subject: fix build for MSVC 2010 The Windows version for QS_TOUCH and QS_POINTER was slightly off. Change-Id: Idb8a8219e09c6aa1a1b24e45b9da640c8d4b7161 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qeventdispatcher_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 64ad2ff0d3..7debf0d774 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -435,10 +435,10 @@ static inline UINT inputTimerMask() UINT result = QS_TIMER | QS_INPUT | QS_RAWINPUT; // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8. -#if WINVER > 0x0601 +#if WINVER > 0x0602 if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) result &= ~(QS_TOUCH | QS_POINTER); -#endif // WINVER > 0x0601 +#endif // WINVER > 0x0602 return result; } -- cgit v1.2.3 From b8d0fac5a92984c432271530e2d3560ec0f1d442 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 4 Apr 2014 12:01:03 +0200 Subject: QGuiApplication: fix crash caused by posting fake mouse event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Qt expects a mouse press/release event to not change mouse position in the same event, QGuiApplicationPrivate::processMouseEvent will detect if a QWindowSystemInterfacePrivate::MouseEvent tries to do this and convert it to two events; one move and one press/release. The problem is that the extra mouse event gets posted. So if delivering the first event causes a flush in the event queue (which can easily happen if e.g calling processEvents), the second event will be processed before the first returns. On iOS we see a crash with DnD as result of this, since drag data gets deleted on mouse release, and returning back to a mouse move after that will cause dangling pointers. This patch will instead of posting the event, call the event handler recursively with the faked event as argument. That way a flush will not cause the "pending" event to be delivered. Change-Id: Id9d88053b4859083fedd666584815016d67ac51b Reviewed-by: Tor Arne Vestbø Reviewed-by: Laszlo Agocs Reviewed-by: Friedemann Kleint --- src/gui/kernel/qguiapplication.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index f96bdc39a6..bdedc9d75f 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1609,14 +1609,17 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e) { QEvent::Type type; - // move first Qt::MouseButtons stateChange = e->buttons ^ buttons; - const bool frameStrut = e->type == QWindowSystemInterfacePrivate::FrameStrutMouse; if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) { - QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent = - new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers); - QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop - stateChange = Qt::NoButton; + // A mouse event should not change both position and buttons at the same time. Instead we + // should first send a move event followed by a button changed event. Since this is not the case + // with the current event, we fake a move-only event that we recurse and process first. This + // will update the global mouse position and cause the second event to be a button only event. + QWindowSystemInterfacePrivate::MouseEvent moveEvent(e->window.data(), + e->timestamp, e->type, e->localPos, e->globalPos, buttons, e->modifiers); + processMouseEvent(&moveEvent); + Q_ASSERT(e->globalPos == QGuiApplicationPrivate::lastCursorPosition); + // continue with processing mouse button change event } QWindow *window = e->window.data(); @@ -1635,6 +1638,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo Qt::MouseButton button = Qt::NoButton; bool doubleClick = false; + const bool frameStrut = e->type == QWindowSystemInterfacePrivate::FrameStrutMouse; if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) { type = frameStrut ? QEvent::NonClientAreaMouseMove : QEvent::MouseMove; -- cgit v1.2.3 From abbdb4d98d13e78cf47cca3c1d6a049770c57750 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 3 Apr 2014 17:52:10 +0200 Subject: QComboBox: Use native popups on Mac This remains an opt-in solution bound to the usage of SH_ComboBox_UseNativePopup in a proxy style. The midterm goal is to make this option on by default, possibly in 5.4. This solution is and will remain a hint in the sense that some exotic use cases of QComboBox (e.g., when setting its view) are inherently incompatible with the native popup idea. Task-number: QTBUG-32731 Change-Id: I2a3d780795c22f9989e44325fcaf314538b1de49 Reviewed-by: Jens Bache-Wiig --- src/widgets/widgets/qcombobox.cpp | 96 ++++++++++++++++++++++++++++++++++++--- src/widgets/widgets/qcombobox_p.h | 4 ++ 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index e0f5ac1050..1ba08bd25f 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -44,6 +44,7 @@ #ifndef QT_NO_COMBOBOX #include #include +#include #include #include #include @@ -205,7 +206,7 @@ void QComboBoxPrivate::updateArrow(QStyle::StateFlag state) arrowState = state; QStyleOptionComboBox opt; q->initStyleOption(&opt); - q->update(q->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, q)); + q->update(q->rect()); } void QComboBoxPrivate::_q_modelReset() @@ -2375,6 +2376,79 @@ QSize QComboBox::sizeHint() const return d->recomputeSizeHint(d->sizeHint); } +#ifdef Q_OS_OSX +/*! + * \internal + * + * Tries to show a native popup. Returns true if it could, false otherwise. + * + */ +bool QComboBoxPrivate::showNativePopup() +{ + Q_Q(QComboBox); + + QPlatformTheme *theme = QGuiApplicationPrivate::instance()->platformTheme(); + if (QPlatformMenu *menu = theme->createPlatformMenu()) { + int itemsCount = q->count(); + + struct IndexSetter { + int index; + QComboBox *cb; + + void operator()(void) { cb->setCurrentIndex(index); } + }; + + QList items; + items.reserve(itemsCount); + QPlatformMenuItem *currentItem = 0; + int currentIndex = q->currentIndex(); + + for (int i = 0; i < itemsCount; ++i) { + QPlatformMenuItem *item = theme->createPlatformMenuItem(); + QModelIndex rowIndex = model->index(i, modelColumn, root); + QVariant textVariant = model->data(rowIndex, Qt::EditRole); + item->setText(textVariant.toString()); + QVariant iconVariant = model->data(rowIndex, Qt::DecorationRole); + if (iconVariant.canConvert()) + item->setIcon(iconVariant.value()); + item->setCheckable(true); + item->setChecked(i == currentIndex); + if (!currentItem || i == currentIndex) + currentItem = item; + + IndexSetter setter = { i, q }; + QObject::connect(item, &QPlatformMenuItem::activated, setter); + + menu->insertMenuItem(item, 0); + menu->syncMenuItem(item); + } + + QWindow *tlw = q->window()->windowHandle(); + menu->setFont(q->font()); + menu->setMinimumWidth(q->rect().width()); + QPoint offset = QPoint(0, 7); + if (q->testAttribute(Qt::WA_MacSmallSize)) + offset = QPoint(-1, 7); + else if (q->testAttribute(Qt::WA_MacMiniSize)) + offset = QPoint(-2, 6); + menu->showPopup(tlw, tlw->mapFromGlobal(q->mapToGlobal(offset)), currentItem); + menu->deleteLater(); + Q_FOREACH (QPlatformMenuItem *item, items) + item->deleteLater(); + + // The Cocoa popup will swallow any mouse release event. + // We need to fake one here to un-press the button. + QMouseEvent mouseReleased(QEvent::MouseButtonRelease, q->pos(), Qt::LeftButton, + Qt::MouseButtons(Qt::LeftButton), Qt::KeyboardModifiers()); + qApp->sendEvent(q, &mouseReleased); + + return true; + } + + return false; +} +#endif // Q_OS_OSX + /*! Displays the list of items in the combobox. If the list is empty then the no items will be shown. @@ -2390,6 +2464,21 @@ void QComboBox::showPopup() if (count() <= 0) return; + QStyle * const style = this->style(); + QStyleOptionComboBox opt; + initStyleOption(&opt); + const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this); + +#ifdef Q_OS_OSX + if (usePopup + && (!d->container + || (view()->metaObject()->className() == QByteArray("QComboBoxListView") + && view()->itemDelegate()->metaObject()->className() == QByteArray("QComboMenuDelegate"))) + && style->styleHint(QStyle::SH_ComboBox_UseNativePopup, &opt, this) + && d->showNativePopup()) + return; +#endif // Q_OS_OSX + #ifdef QT_KEYPAD_NAVIGATION #ifndef QT_NO_COMPLETER if (QApplication::keypadNavigationEnabled() && d->completer) { @@ -2401,14 +2490,10 @@ void QComboBox::showPopup() #endif #endif - QStyle * const style = this->style(); - // set current item and select it view()->selectionModel()->setCurrentIndex(d->currentIndex, QItemSelectionModel::ClearAndSelect); QComboBoxPrivateContainer* container = d->viewContainer(); - QStyleOptionComboBox opt; - initStyleOption(&opt); QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxListBoxPopup, this)); QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this)); @@ -2419,7 +2504,6 @@ void QComboBox::showPopup() int aboveHeight = above.y() - screen.y(); bool boundToScreen = !window()->testAttribute(Qt::WA_DontShowOnScreen); - const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this); { int listHeight = 0; int count = 0; diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index 1ad2aa455a..dceffe8d35 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -377,6 +377,10 @@ public: void modelChanged(); void updateViewContainerPaletteAndOpacity(); +#ifdef Q_OS_OSX + bool showNativePopup(); +#endif + QAbstractItemModel *model; QLineEdit *lineEdit; QComboBoxPrivateContainer *container; -- cgit v1.2.3 From 1a4fc0a129e330b9d80f87cb3e16ffe3b2968fab Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 4 Apr 2014 14:08:45 +0200 Subject: QStyle: Add new SH_ComboBox_UseNativePopup style hint If the style hints it, QComboBox::showPopup() will try to show a native popup instead. This is currently undocumented and an opt-in feature (typically by using a proxy style). Works only on Mac so far. Task-number: QTBUG-32731 Change-Id: I4447e884cbd6b490f3039c7a95168698c0bed16e Reviewed-by: Jens Bache-Wiig --- src/widgets/styles/qstyle.cpp | 3 +++ src/widgets/styles/qstyle.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index d244c10316..4c5c7cd17e 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1750,6 +1750,9 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value SH_ComboBox_Popup Allows popups as a combobox drop-down menu. + \omitvalue SH_ComboBox_UseNativePopup Whether we should use a native popup. + Only supported for non-editable combo boxes on Mac OS X so far. + \value SH_Workspace_FillSpaceOnMaximize The workspace should maximize the client area. diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index 04112169ca..136daa9abd 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -702,6 +702,7 @@ public: SH_ToolTip_FallAsleepDelay, SH_Widget_Animate, SH_Splitter_OpaqueResize, + SH_ComboBox_UseNativePopup, // Add new style hint values here SH_CustomBase = 0xf0000000 -- cgit v1.2.3 From 362c75f7c10cb6aefdc638142dd3f8e1a74329cc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 4 Apr 2014 19:02:49 +0200 Subject: in command line args, escape tabs as well Task-number: QTBUG-27154 Change-Id: I4a204b2bf2231027db55a444f304190c3b30878c Reviewed-by: Joerg Bornemann --- qmake/generators/unix/unixmake.cpp | 3 ++- qmake/generators/win32/winmakefile.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index c11259d5a1..4c3df4efe8 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -921,7 +921,8 @@ UnixMakefileGenerator::escapeFilePath(const QString &path) const { QString ret = path; if(!ret.isEmpty()) { - ret = unescapeFilePath(ret).replace(QLatin1Char(' '), QLatin1String("\\ ")); + ret = unescapeFilePath(ret).replace(QLatin1Char(' '), QLatin1String("\\ ")) + .replace(QLatin1Char('\t'), QLatin1String("\\\t")); debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); } return ret; diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 484062d56e..da81b85e2a 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -883,7 +883,7 @@ QString Win32MakefileGenerator::escapeFilePath(const QString &path) const QString ret = path; if(!ret.isEmpty()) { ret = unescapeFilePath(ret); - if(ret.contains(" ")) + if (ret.contains(' ') || ret.contains('\t')) ret = "\"" + ret + "\""; debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); } -- cgit v1.2.3 From 9c2ecf89eb773b4929d39a0a4929ce2b647aaaef Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 26 Mar 2014 09:40:52 -0400 Subject: network: finish all pending replies upon error ... and not only one. This was a problem e.g. when there were several requests to the same host and the host was not reachable; only one reply would get an error signal in case we suppressed other errors in "happy eyeballs" host lookup style. Task-number: QTBUG-36890 Change-Id: I1b5757498bd644b0d773cf6c43e4950620949c5c Reviewed-by: Richard J. Moore --- .../access/qhttpnetworkconnectionchannel.cpp | 27 +++++++++------ .../access/qnetworkreply/tst_qnetworkreply.cpp | 40 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index fb40958178..169124e9f4 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -873,18 +873,23 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket if (!connection->d_func()->shouldEmitChannelError(socket)) return; - // Need to dequeu the request so that we can emit the error. - if (!reply) - connection->d_func()->dequeueRequest(socket); - if (reply) { - reply->d_func()->errorString = errorString; - emit reply->finishedWithError(errorCode, errorString); - reply = 0; - if (protocolHandler) - protocolHandler->setReply(0); - } + // emit error for all waiting replies + do { + // Need to dequeu the request so that we can emit the error. + if (!reply) + connection->d_func()->dequeueRequest(socket); + + if (reply) { + reply->d_func()->errorString = errorString; + emit reply->finishedWithError(errorCode, errorString); + reply = 0; + if (protocolHandler) + protocolHandler->setReply(0); + } + } while (!connection->d_func()->highPriorityQueue.isEmpty() + || !connection->d_func()->lowPriorityQueue.isEmpty()); #ifndef QT_NO_SSL - else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) { + if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) { QList spdyPairs = spdyRequestsToSend.values(); for (int a = 0; a < spdyPairs.count(); ++a) { // emit error for all replies diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 11ea8aebc8..fbac7dc77c 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -177,6 +177,7 @@ public Q_SLOTS: void authenticationRequired(QNetworkReply*,QAuthenticator*); void proxyAuthenticationRequired(const QNetworkProxy &,QAuthenticator*); void pipeliningHelperSlot(); + void emitErrorForAllRepliesSlot(); #ifndef QT_NO_SSL void sslErrors(QNetworkReply*,const QList &); @@ -449,6 +450,8 @@ private Q_SLOTS: void ftpAuthentication_data(); void ftpAuthentication(); + void emitErrorForAllReplies(); // QTBUG-36890 + #ifdef QT_BUILD_INTERNAL void backgroundRequest_data(); void backgroundRequest(); @@ -7465,6 +7468,12 @@ void tst_QNetworkReply::pipeliningHelperSlot() { } } +void tst_QNetworkReply::emitErrorForAllRepliesSlot() { + static int a = 0; + if (++a == 3) + QTestEventLoop::instance().exitLoop(); +} + void tst_QNetworkReply::closeDuringDownload_data() { QTest::addColumn("url"); @@ -7513,6 +7522,37 @@ void tst_QNetworkReply::ftpAuthentication() QCOMPARE(reply->error(), QNetworkReply::NetworkError(error)); } +void tst_QNetworkReply::emitErrorForAllReplies() // QTBUG-36890 +{ + // port 100 is not well-known and should be closed + QList urls = QList() << QUrl("http://localhost:100/request1") + << QUrl("http://localhost:100/request2") + << QUrl("http://localhost:100/request3"); + QList replies; + QList errorSpies; + QList finishedSpies; + for (int a = 0; a < urls.count(); ++a) { + QNetworkRequest request(urls.at(a)); + QNetworkReply *reply = manager.get(request); + replies.append(reply); + QSignalSpy *errorSpy = new QSignalSpy(reply, SIGNAL(error(QNetworkReply::NetworkError))); + errorSpies.append(errorSpy); + QSignalSpy *finishedSpy = new QSignalSpy(reply, SIGNAL(finished())); + finishedSpies.append(finishedSpy); + QObject::connect(reply, SIGNAL(finished()), SLOT(emitErrorForAllRepliesSlot())); + } + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + for (int a = 0; a < urls.count(); ++a) { + QVERIFY(replies.at(a)->isFinished()); + QCOMPARE(errorSpies.at(a)->count(), 1); + errorSpies.at(a)->deleteLater(); + QCOMPARE(finishedSpies.at(a)->count(), 1); + finishedSpies.at(a)->deleteLater(); + replies.at(a)->deleteLater(); + } +} + #ifdef QT_BUILD_INTERNAL void tst_QNetworkReply::backgroundRequest_data() { -- cgit v1.2.3 From d9077669a114775273779d42f466175fbd4ad725 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 7 Apr 2014 13:53:36 +0200 Subject: tst_QTreeView: fix use of uninited variable Valgrind complained: ==13941== Conditional jump or move depends on uninitialised value(s) ==13941== at 0x4206FC: tst_QTreeView::styleOptionViewItem()::MyDelegate::paint(QPainter*, QStyleOptionViewItem const&, QModelIndex const&) const (tst_qtreeview.cpp:3062) [...] Change-Id: I76da01c191415ba0a00b4b85312f2fe08e4ee2d2 Reviewed-by: Friedemann Kleint --- tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index b07009aa3c..0579914940 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -3047,7 +3047,13 @@ void tst_QTreeView::styleOptionViewItem() static const char* s_pos[] = { "Invalid", "Beginning", "Middle", "End", "OnlyOne" }; return s_pos[pos]; } - public: + public: + MyDelegate() + : QStyledItemDelegate(), + count(0), + allCollapsed(false) + {} + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const { QVERIFY(qstyleoption_cast(&option)); -- cgit v1.2.3 From 51108317216d7528e76dbf666a37a3dfa830536c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Apr 2014 00:58:08 +0200 Subject: QPageLayout: use existing qBound() instead of rolling our own qt_clamp(). Change-Id: I2729ae3ff98e8c29c66f0f5c792b1bc7bf586f06 Reviewed-by: Friedemann Kleint --- src/gui/painting/qpagelayout.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp index 7ae117e423..3f29a9d1f3 100644 --- a/src/gui/painting/qpagelayout.cpp +++ b/src/gui/painting/qpagelayout.cpp @@ -50,11 +50,6 @@ QT_BEGIN_NAMESPACE -static qreal qt_clamp(qreal value, qreal min, qreal max) -{ - return qMin(qMax(value, min), max); -} - // Multiplier for converting units to points. Q_GUI_EXPORT qreal qt_pointMultiplier(QPageLayout::Unit unit) { @@ -221,10 +216,10 @@ bool QPageLayoutPrivate::isValid() const void QPageLayoutPrivate::clampMargins(const QMarginsF &margins) { - m_margins = QMarginsF(qt_clamp(margins.left(), m_minMargins.left(), m_maxMargins.left()), - qt_clamp(margins.top(), m_minMargins.top(), m_maxMargins.top()), - qt_clamp(margins.right(), m_minMargins.right(), m_maxMargins.right()), - qt_clamp(margins.bottom(), m_minMargins.bottom(), m_maxMargins.bottom())); + m_margins = QMarginsF(qBound(m_minMargins.left(), margins.left(), m_maxMargins.left()), + qBound(m_minMargins.top(), margins.top(), m_maxMargins.top()), + qBound(m_minMargins.right(), margins.right(), m_maxMargins.right()), + qBound(m_minMargins.bottom(), margins.bottom(), m_maxMargins.bottom())); } QMarginsF QPageLayoutPrivate::margins(QPageLayout::Unit units) const -- cgit v1.2.3 From d03cc17a6cf17b1427307034edd7d3589ede4aef Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 4 Apr 2014 14:38:22 +0200 Subject: Android: use glyph cache resizing workaround with Vivante GC1000 GPU. Task-number: QTBUG-38102 Change-Id: I9f423e15b9cbc3d2f424871f47795052b1f53e09 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/qandroidplatformopenglcontext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp index 289480c625..152a06c99d 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp @@ -71,7 +71,8 @@ bool QAndroidPlatformOpenGLContext::needsFBOReadBackWorkaroud() const char *rendererString = reinterpret_cast(glGetString(GL_RENDERER)); needsWorkaround = qstrcmp(rendererString, "Mali-400 MP") == 0 - || qstrcmp(rendererString, "Adreno (TM) 200") == 0; + || qstrcmp(rendererString, "Adreno (TM) 200") == 0 + || qstrcmp(rendererString, "GC1000 core") == 0; set = true; } -- cgit v1.2.3 From 8b50386b087d6e330ad20cde14b98d923397517d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 1 Apr 2014 15:05:20 +0200 Subject: Use PlistBuddy instead of sed/xpath magic to extract OS X/iOS SDK name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I9e9f9b033cc892a35c86b35f64dc1dd915ad44f3 Reviewed-by: Oswald Buddenhagen Reviewed-by: Eike Ziller Reviewed-by: Jake Petroules Reviewed-by: Tor Arne Vestbø --- mkspecs/features/mac/sdk.prf | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf index 5b5186a14b..36bff00496 100644 --- a/mkspecs/features/mac/sdk.prf +++ b/mkspecs/features/mac/sdk.prf @@ -45,12 +45,7 @@ for(tool, $$list(QMAKE_CC QMAKE_CXX QMAKE_FIX_RPATH QMAKE_AR QMAKE_RANLIB QMAKE_ } isEmpty(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_name) { - # We use xml as the output format instead of json since plutil on 10.6 does not have that option - QMAKE_MAC_PLATFORM_NAME = $$system("/usr/bin/plutil -convert xml1 \"$$QMAKE_MAC_SDK_PATH/SDKSettings.plist\" -o - 2>/dev/null | " \ - "sed '/^/dev/null | " \ - "sed 's/.*Value: \\(.*\\)/\\1/'") - + QMAKE_MAC_PLATFORM_NAME = $$system("/usr/libexec/PlistBuddy -c 'print DefaultProperties:PLATFORM_NAME' $$QMAKE_MAC_SDK_PATH/SDKSettings.plist 2>/dev/null") isEmpty(QMAKE_MAC_PLATFORM_NAME): error("Could not resolve platform name for SDK '$$QMAKE_MAC_SDK'") cache(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_name, set stash, QMAKE_MAC_PLATFORM_NAME) } else { -- cgit v1.2.3 From b81898f1dba00974e4ff7a16c2cb9abe03d2211c Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Mon, 7 Apr 2014 12:05:38 +0200 Subject: Don't skip QtLocation on iOS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QtPositioning is supported on iOS since Qt 5.3. Task-number: QTBUG-37792 Change-Id: I74729f0c99c49858032b68dd0e7c9e628ae77b12 Reviewed-by: Tor Arne Vestbø --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index d63baad87a..4d8c280bba 100755 --- a/configure +++ b/configure @@ -3103,7 +3103,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then CFG_PKGCONFIG="no" CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples" CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store - CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtlocation qtmacextras qtserialport qttools qtwebkit qtwebkit-examples" + CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtmacextras qtserialport qttools qtwebkit qtwebkit-examples" # If the user passes -sdk on the command line we build a SDK-specific Qt build. # Otherwise we build a joined simulator and device build, which is the default. -- cgit v1.2.3 From c33849d0cbfbe0c33170d8e3a49f89b22fd76246 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 7 Apr 2014 13:49:17 -0700 Subject: Don't redefine dynamic_cast if it's already a macro Redefining macros is always a bad idea. On top of that, MSVC doesn't like when we #define dynamic_cast, even though the C++ standard explicitly allows it. Task-number: QTBUG-29093 Change-Id: I6e33d609ce213cf6a9085faa3f991a873d825dc6 Reviewed-by: Olivier Goffart --- src/corelib/global/qglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 9b5d78b6fe..fba8b019e7 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -980,7 +980,7 @@ Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1); dynamic_cast to cause a compile failure. */ -#ifdef QT_NO_DYNAMIC_CAST +#if defined(QT_NO_DYNAMIC_CAST) && !defined(dynamic_cast) # define dynamic_cast QT_PREPEND_NAMESPACE(qt_dynamic_cast_check) template -- cgit v1.2.3 From 0ed1042092f6cc514ed604583b6f90d3b826d2cf Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Fri, 4 Apr 2014 15:10:29 +0100 Subject: Fix QNetworkRequest::setRawHeader() for QT_NO_CAST_FROM_BYTEARRAY Avoid the implicit conversion in the doc snippet. Change-Id: Iacec6dab371a22c16f537af471f6653d9c5ad43d Reviewed-by: Andy Shaw --- src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp b/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp index 53eadda7e9..61e7cf0ea3 100644 --- a/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp +++ b/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp @@ -39,5 +39,5 @@ ****************************************************************************/ //! [0] -request.setRawHeader("Last-Modified", "Sun, 06 Nov 1994 08:49:37 GMT"); +request.setRawHeader(QByteArray("Last-Modified"), QByteArray("Sun, 06 Nov 1994 08:49:37 GMT")); //! [0] -- cgit v1.2.3 From fbeb43135feadbdfcd48b6717b5cb4017325cd1d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Mar 2014 23:19:17 -0800 Subject: Mark Variable Length Arrays as a TS feature for C++14 The feature was removed from the C++14 draft standard and moved instead to a Technical Specification. Since we don't know how to enable TS features in GCC 4.9 yet, remove it from the definition. The Clang definition is probably safe, since it is behind an #if __has_extension. Change-Id: Ibc32b35657b046680078b39a7678bd8e1e5395d2 Reviewed-by: Olivier Goffart Reviewed-by: Marc Mutz --- src/corelib/global/qcompilerdetection.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 6755b82f61..00f209ad6d 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -483,6 +483,8 @@ * N3652 Q_COMPILER_RELAXED_CONSTEXPR_FUNCTIONS * N3386 N3638 Q_COMPILER_RETURN_TYPE_DEDUCTION * N3651 Q_COMPILER_VARIABLE_TEMPLATES + * + * C++14 Technical Specifications / C++17: * N3639 Q_COMPILER_VLA (see also Q_COMPILER_RESTRICTED_VLA) * */ @@ -774,7 +776,6 @@ //# define Q_COMPILER_BINARY_LITERALS // already supported since GCC 4.3 as an extension # define Q_COMPILER_LAMBDA_CAPTURES # define Q_COMPILER_RETURN_TYPE_DEDUCTION -# define Q_COMPILER_VLA # endif # endif #endif -- cgit v1.2.3 From 6ea574d4461199e036fb9cd05b1bbdb0f93c390c Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 7 Apr 2014 14:02:29 +0200 Subject: QNetworkReplyHttpImpl: fix misuse of QDateTime::addSecs() QDateTime::addSecs() is a const function and returns a new QDateTime with the given seconds added, thus the current statement had no effect. Found by applying Q_REQUIRED_RESULT in dev branch. Change-Id: Id712334f91e0adb40bafc23470bf46479334c81a Reviewed-by: Richard J. Moore --- src/network/access/qnetworkreplyhttpimpl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index de4c8d0964..f043307c10 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -560,8 +560,7 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h if (!expirationDate.isValid()) { if (lastModified.isValid()) { int diff = currentDateTime.secsTo(lastModified); - expirationDate = lastModified; - expirationDate.addSecs(diff / 10); + expirationDate = lastModified.addSecs(diff / 10); if (httpRequest.headerField("Warning").isEmpty()) { QDateTime dt; dt.setTime_t(current_age); -- cgit v1.2.3 From d2f5fdb20d30638c82f6d26fff92b73b84f1e1b2 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 7 Apr 2014 14:03:16 +0200 Subject: QCUPSSupport: fix misuse of QDateTime::addDays() QDateTime::addDays() is a const function and returns a new QDateTime with the given days added, thus the current statement had no effect. Found by applying Q_REQUIRED_RESULT in dev branch. Change-Id: I1b061619d45d7806feaa2bf9fb6d9f0b43d63def Reviewed-by: Richard J. Moore Reviewed-by: Thiago Macieira --- src/printsupport/kernel/qcups.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index a1c657eda4..c6e3ddb54d 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -113,7 +113,7 @@ void QCUPSSupport::setJobHold(QPrinter *printer, const JobHoldUntil jobHold, con QDateTime localDateTime = QDateTime::currentDateTime(); // Check if time is for tomorrow in case of DST change overnight if (holdUntilTime < localDateTime.time()) - localDateTime.addDays(1); + localDateTime = localDateTime.addDays(1); localDateTime.setTime(holdUntilTime); setCupsOption(cupsOptions, QStringLiteral("job-hold-until"), -- cgit v1.2.3 From 30e6d442ff6fd140e18fca7c5b203b87507854c8 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 3 Apr 2014 17:48:17 +0200 Subject: Mac style: Fix one-pixel offset for combo boxes in small size Change-Id: I744c102bd086742b1052ed547e50037dddff4654 Reviewed-by: Jens Bache-Wiig --- src/widgets/styles/qmacstyle_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 08221ce83a..2d8489f47f 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -3721,7 +3721,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QStyleOptionComboBox comboCopy = *cb; comboCopy.direction = Qt::LeftToRight; if ((opt->state & QStyle::State_Small) && QSysInfo::macVersion() > QSysInfo::MV_10_6) - comboCopy.rect.translate(0, w ? -1 : -2); // Supports Qt Quick Controls + comboCopy.rect.translate(0, w ? (QSysInfo::macVersion() > QSysInfo::MV_10_8 ? 0 : -1) : -2); // Supports Qt Quick Controls else if (QSysInfo::macVersion() > QSysInfo::MV_10_8) comboCopy.rect.translate(0, 1); QCommonStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w); -- cgit v1.2.3 From 118494aeda916a63dd94474442f9dbf7b2ad7ff5 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 7 Apr 2014 13:22:12 +0200 Subject: HB-NG on Mac: Fix PDF in end of string The CoreText engine will remove the PDF token from the end of the string (instead of producing a zero-width glyph for it), thus the output will be different from the OpenType backend and Qt will get confused. To fix this, we emulate the expected behavior by molding the output in a special case. This is a port of e45c4387ae16627d61e30a58ae901d888d375aa7 from Qt 4. Task-number: QTBUG-38113 Change-Id: Ia0a078e3a60317981d4d5a4ee7e575a1714a1d75 Reviewed-by: Konstantin Ritt --- src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index 40c06371bd..09f3171b30 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -691,11 +691,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, CFDictionaryRef attributes = CTRunGetAttributes (run); CTFontRef run_ct_font = static_cast(CFDictionaryGetValue (attributes, kCTFontAttributeName)); CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0); + + CFRange range = CTRunGetStringRange (run); if (!CFEqual (run_cg_font, face_data->cg_font)) { CFRelease (run_cg_font); - CFRange range = CTRunGetStringRange (run); buffer->ensure (buffer->len + range.length); if (buffer->in_error) FAIL ("Buffer resize failed"); @@ -732,11 +733,16 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, } CFRelease (run_cg_font); + /* CoreText throws away the PDF token, while the OpenType backend will add a zero-advance + * glyph for this. We need to make sure the two produce the same output. */ + UniChar endGlyph = CFStringGetCharacterAtIndex(string_ref, range.location + range.length - 1); + bool endWithPDF = endGlyph == 0x202c; + unsigned int num_glyphs = CTRunGetGlyphCount (run); if (num_glyphs == 0) continue; - buffer->ensure (buffer->len + num_glyphs); + buffer->ensure (buffer->len + num_glyphs + (endWithPDF ? 1 : 0)); scratch = buffer->get_scratch_buffer (&scratch_size); @@ -783,6 +789,20 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, buffer->len++; } + + if (endWithPDF) { + hb_glyph_info_t *info = &buffer->info[buffer->len]; + + info->codepoint = 0xffff; + info->cluster = range.location + range.length - 1; + + /* Currently, we do all x-positioning by setting the advance, we never use x-offset. */ + info->mask = 0; + info->var1.u32 = 0; + info->var2.u32 = 0; + + buffer->len++; + } } buffer->clear_positions (); -- cgit v1.2.3 From c6720d87218915f2557d9698218a22c1d46b4950 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Fri, 4 Apr 2014 17:42:05 +0200 Subject: QNX: Destroy window buffers when resized QNX version of screen doesn't reallocate window buffers dynamically. The buffers have to be destroyed and recreated when a window is resized. As the overhead is minimal this will be done on BlackBerry, as well. Change-Id: I488942879822c64a6ab1871ebf5d6da9aec144d6 Reviewed-by: Fabian Bumberger --- src/plugins/platforms/qnx/qqnxeglwindow.cpp | 19 +++++------- src/plugins/platforms/qnx/qqnxeglwindow.h | 3 -- src/plugins/platforms/qnx/qqnxwindow.cpp | 46 +++++++++++++++-------------- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp index f1f9f5469c..9d40d166af 100644 --- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp @@ -81,15 +81,14 @@ QQnxEglWindow::~QQnxEglWindow() void QQnxEglWindow::createEGLSurface() { - // Fetch the surface size from the window and update - // the window's buffers before we create the EGL surface - const QSize surfaceSize = requestedBufferSize(); - if (!surfaceSize.isValid()) { + if (!m_requestedBufferSize.isValid()) { qWarning("QQNX: Trying to create 0 size EGL surface. " "Please set a valid window size before calling QOpenGLContext::makeCurrent()"); return; } - setBufferSize(surfaceSize); + + // update the window's buffers before we create the EGL surface + setBufferSize(m_requestedBufferSize); const EGLint eglSurfaceAttrs[] = { @@ -99,9 +98,10 @@ void QQnxEglWindow::createEGLSurface() qEglWindowDebug() << "Creating EGL surface" << platformOpenGLContext()->getEglDisplay() << platformOpenGLContext()->getEglConfig(); + // Create EGL surface - m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay() - , platformOpenGLContext()->getEglConfig(), + m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay(), + platformOpenGLContext()->getEglConfig(), (EGLNativeWindowType) nativeHandle(), eglSurfaceAttrs); if (m_eglSurface == EGL_NO_SURFACE) { const EGLenum error = QQnxGLContext::checkEGLError("eglCreateWindowSurface"); @@ -171,11 +171,6 @@ void QQnxEglWindow::setGeometry(const QRect &rect) QQnxWindow::setGeometry(newGeometry); } -QSize QQnxEglWindow::requestedBufferSize() const -{ - return m_requestedBufferSize; -} - void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext) { // This function does not take ownership of the platform gl context. diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h index a6a223c58e..cd98f9369d 100644 --- a/src/plugins/platforms/qnx/qqnxeglwindow.h +++ b/src/plugins/platforms/qnx/qqnxeglwindow.h @@ -65,9 +65,6 @@ public: void setGeometry(const QRect &rect); - // Called by QQnxGLContext::createSurface() - QSize requestedBufferSize() const; - protected: int pixelFormat() const; void resetBuffers(); diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 42318729b1..2e0febff20 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -353,37 +353,39 @@ void QQnxWindow::setBufferSize(const QSize &size) { qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size; - // Set window buffer size // libscreen fails when creating empty buffers const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size; + int format = pixelFormat(); + + if (nonEmptySize == m_bufferSize || format == -1) + return; + + Q_SCREEN_CRITICALERROR( + screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, &format), + "Failed to set window format"); + + if (m_bufferSize.isValid()) { + // destroy buffers first, if resized + Q_SCREEN_CRITICALERROR(screen_destroy_window_buffers(m_window), + "Failed to destroy window buffers"); + } int val[2] = { nonEmptySize.width(), nonEmptySize.height() }; Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val), "Failed to set window buffer size"); - // Create window buffers if they do not exist - if (m_bufferSize.isEmpty()) { - val[0] = pixelFormat(); - if (val[0] == -1) // The platform GL context was not set yet on the window, so we can't procede - return; - - Q_SCREEN_CRITICALERROR( - screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val), - "Failed to set window format"); + Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT), + "Failed to create window buffers"); - Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT), - "Failed to create window buffers"); + // check if there are any buffers available + int bufferCount = 0; + Q_SCREEN_CRITICALERROR( + screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount), + "Failed to query render buffer count"); - // check if there are any buffers available - int bufferCount = 0; - Q_SCREEN_CRITICALERROR( - screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount), - "Failed to query render buffer count"); - - if (bufferCount != MAX_BUFFER_COUNT) { - qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d. You might experience problems.", - MAX_BUFFER_COUNT, bufferCount); - } + if (bufferCount != MAX_BUFFER_COUNT) { + qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d.", + MAX_BUFFER_COUNT, bufferCount); } // Set the transparency. According to QNX technical support, setting the window -- cgit v1.2.3 From f6dce4c858e525b7f2adc4f5f5e6e92152d2a002 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Thu, 3 Apr 2014 17:44:38 +0200 Subject: QNX: Fix QGraphicsView autotests On BlackBerry first window is always shown full screen. However, many tests rely on a specific window size. A dummy full screen window is created so subsequent windows have correct size. Change-Id: Id8bd0212b6eca677953e78505459e3cd69bc6328 Reviewed-by: Fabian Bumberger --- .../qgraphicsview/tst_qgraphicsview.cpp | 35 ++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 37cc6522a2..c8f76c36ff 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -274,6 +274,11 @@ private slots: public slots: void dummySlot() {} + +private: +#if defined Q_OS_BLACKBERRY + QScopedPointer rootWindow; +#endif }; void tst_QGraphicsView::initTestCase() @@ -281,6 +286,13 @@ void tst_QGraphicsView::initTestCase() #ifdef Q_OS_WINCE_WM qApp->setAutoMaximizeThreshold(-1); #endif + +#if defined Q_OS_BLACKBERRY + // On BlackBerry first window is always shown full screen. However, many tests rely on specific + // window sizes. Create a dummy full screen window, so subsequent windows have correct size. + rootWindow.reset(new QWidget); + rootWindow->show(); +#endif } void tst_QGraphicsView::cleanup() @@ -1300,7 +1312,7 @@ void tst_QGraphicsView::fitInView() view.setFixedSize(400, 200); #endif - view.show(); + view.showNormal(); view.fitInView(scene.itemsBoundingRect(), Qt::IgnoreAspectRatio); qApp->processEvents(); @@ -1412,7 +1424,7 @@ void tst_QGraphicsView::itemsAtPosition() view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view.setScene(&scene); - view.show(); + view.showNormal(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QPoint screenPos = view.viewport()->mapToGlobal(viewPos); @@ -1530,7 +1542,7 @@ void tst_QGraphicsView::itemsInRect_cosmeticAdjust() view.setRenderHint(QPainter::Antialiasing, adjustForAntialiasing); view.setFrameStyle(0); view.resize(300, 300); - view.show(); + view.showNormal(); QVERIFY(QTest::qWaitForWindowActive(&view)); QTRY_VERIFY(rect->numPaints > 0); @@ -2524,9 +2536,9 @@ public: bool dirtyPainter; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *w) { - dirtyPainter = (painter->pen().color() != Qt::black); + dirtyPainter = (painter->pen().color() != w->palette().color(w->foregroundRole())); painter->setPen(Qt::red); } }; @@ -2801,7 +2813,7 @@ void tst_QGraphicsView::scrollBarRanges() view.setHorizontalScrollBarPolicy(hbarpolicy); view.setVerticalScrollBarPolicy(vbarpolicy); - view.show(); + view.showNormal(); QVERIFY(QTest::qWaitForWindowExposed(&view)); const int offset = view.style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, 0); @@ -3529,7 +3541,7 @@ void tst_QGraphicsView::moveItemWhileScrolling() view.setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing); view.resize(200, 200); view.painted = false; - view.show(); + view.showNormal(); if (changedConnected) QObject::connect(view.scene(), SIGNAL(changed(QList)), this, SLOT(dummySlot())); QVERIFY(QTest::qWaitForWindowExposed(&view)); @@ -4622,7 +4634,7 @@ void tst_QGraphicsView::QTBUG_5859_exposedRect() QGraphicsView view(&scene); view.scale(4.15, 4.15); - view.show(); + view.showNormal(); qApp->setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); @@ -4699,12 +4711,17 @@ void tst_QGraphicsView::hoverLeave() const QPoint outOfWindow = view.geometry().topRight() + QPoint(50, 0); QCursor::setPos(outOfWindow); - view.show(); + view.showNormal(); qApp->setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); QPoint pos = view.viewport()->mapToGlobal(view.mapFromScene(item->mapToScene(10, 10))); QCursor::setPos(pos); + +#if defined(Q_OS_QNX) + QEXPECT_FAIL("", "QCursor does not set native cursor on QNX", Abort); +#endif + QTRY_VERIFY(item->receivedEnterEvent); QCOMPARE(item->enterWidget, view.viewport()); -- cgit v1.2.3 From 53c8a687b46f6ce8c24fabfe924758fe174b6922 Mon Sep 17 00:00:00 2001 From: Jason Haslam Date: Fri, 4 Apr 2014 15:57:30 -0600 Subject: Fix xcb plugin backing store byte order issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The image format of the backing store should use the byte order of the machine where the application is running, not the native format of the X server. Then, if the byte order of the backing store image differs from the X server's native format, it needs to be converted before being sent across the network. Task-number: QTBUG-29898 Change-Id: Ic91c8ffb814c6beeb9f1d9195174a47d8bd94a90 Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 33 +++++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 1579797f85..57d6bc580b 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -94,14 +94,23 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI , m_gc_window(0) { Q_XCB_NOOP(connection()); - m_xcb_image = xcb_image_create_native(xcb_connection(), - size.width(), - size.height(), - XCB_IMAGE_FORMAT_Z_PIXMAP, - depth, - 0, - ~0, - 0); + + const xcb_setup_t *setup = xcb_get_setup(xcb_connection()); + xcb_format_t *fmt = xcb_setup_pixmap_formats(setup); + xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup); + for (; fmt != fmtend; ++fmt) + if (fmt->depth == depth) + break; + + Q_ASSERT(fmt != fmtend); + + m_xcb_image = xcb_image_create(size.width(), size.height(), + XCB_IMAGE_FORMAT_Z_PIXMAP, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, 0, + QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST, + XCB_IMAGE_ORDER_MSB_FIRST, + 0, ~0, 0); const int segmentSize = m_xcb_image->stride * m_xcb_image->height; if (!segmentSize) @@ -209,10 +218,13 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s // at least 16384 bytes. That should be enough for quite large images. Q_ASSERT(rows_per_put > 0); + // Convert the image to the native byte order. + xcb_image_t *converted_image = xcb_image_native(xcb_connection(), m_xcb_image, 1); + while (height > 0) { int rows = std::min(height, rows_per_put); - xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows, + xcb_image_t *subimage = xcb_image_subimage(converted_image, src_x, src_y, width, rows, 0, 0, 0); xcb_image_put(xcb_connection(), window, @@ -228,6 +240,9 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s target_y += rows; height -= rows; } + + if (converted_image != m_xcb_image) + xcb_image_destroy(converted_image); } Q_XCB_NOOP(connection()); -- cgit v1.2.3 From 3a100edc4f912e0f8207e87282227135b90572b0 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 7 Apr 2014 10:04:17 +0200 Subject: QTestCase: fix macros taking expressions to avoid clang warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They were of the form "warning: using the result of an assignment as a condition without parentheses [-Wparentheses]" Change-Id: I049bf0f67073bf41310ca5ee73f17e5e69de569f Reviewed-by: Friedemann Kleint Reviewed-by: J-P Nurmi Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestcase.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index b715d83383..d9c8a43a2a 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -140,7 +140,7 @@ do {\ #define QTRY_TIMEOUT_DEBUG_IMPL(__expr, __timeoutValue, __step)\ if (!(__expr)) { \ - QTRY_LOOP_IMPL(__expr, (2 * __timeoutValue), __step);\ + QTRY_LOOP_IMPL((__expr), (2 * __timeoutValue), __step);\ if (__expr) { \ QString msg = QString::fromUtf8("QTestLib: This test case check (\"%1\") failed because the requested timeout (%2 ms) was too short, %3 ms would have been sufficient this time."); \ msg = msg.arg(QString::fromUtf8(#__expr)).arg(__timeoutValue).arg(__timeoutValue + __i); \ @@ -151,26 +151,26 @@ do {\ #define QTRY_IMPL(__expr, __timeout)\ const int __step = 50; \ const int __timeoutValue = __timeout; \ - QTRY_LOOP_IMPL(__expr, __timeoutValue, __step); \ - QTRY_TIMEOUT_DEBUG_IMPL(__expr, __timeoutValue, __step)\ + QTRY_LOOP_IMPL((__expr), __timeoutValue, __step); \ + QTRY_TIMEOUT_DEBUG_IMPL((__expr), __timeoutValue, __step)\ // Will try to wait for the expression to become true while allowing event processing #define QTRY_VERIFY_WITH_TIMEOUT(__expr, __timeout) \ do { \ - QTRY_IMPL(__expr, __timeout);\ + QTRY_IMPL((__expr), __timeout);\ QVERIFY(__expr); \ } while (0) -#define QTRY_VERIFY(__expr) QTRY_VERIFY_WITH_TIMEOUT(__expr, 5000) +#define QTRY_VERIFY(__expr) QTRY_VERIFY_WITH_TIMEOUT((__expr), 5000) // Will try to wait for the comparison to become successful while allowing event processing #define QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, __timeout) \ do { \ QTRY_IMPL(((__expr) == (__expected)), __timeout);\ - QCOMPARE(__expr, __expected); \ + QCOMPARE((__expr), __expected); \ } while (0) -#define QTRY_COMPARE(__expr, __expected) QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, 5000) +#define QTRY_COMPARE(__expr, __expected) QTRY_COMPARE_WITH_TIMEOUT((__expr), __expected, 5000) #define QSKIP_INTERNAL(statement) \ do {\ -- cgit v1.2.3 From f41418aeb20ddc190892216a09feb564d2cef5b4 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sun, 6 Apr 2014 15:56:08 +0100 Subject: Ensure we initialize things before checking the openssl version. Task-number: QTBUG-37783 Change-Id: Ie276e597062d8bfc74ef57251ed21a94020e030f Reviewed-by: Friedemann Kleint --- src/network/ssl/qsslsocket_openssl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index bcb2254d11..1b3928fdfb 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -569,6 +569,9 @@ void QSslSocketPrivate::ensureInitialized() long QSslSocketPrivate::sslLibraryVersionNumber() { + if (!supportsSsl()) + return 0; + return q_SSLeay(); } -- cgit v1.2.3 From 5fe98ebb376bcbc8728e4ce64b697637404a55e1 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Sun, 6 Apr 2014 20:00:07 -0500 Subject: Prevent QUnifiedTimer from ticking backwards. This could happen in the following situation: * a custom animation driver with fixed delta * a triple-buffering scheme (rendering ahead a frame) * a second animation timer starting while a first was active This would cause QUnifiedTimer::startTimers() to trigger QUnifiedTimer::updateAnimationTimers(-1), and use the current time from the QElapsedTimer rather than the animation driver. This time could be less than the last reported time from the animation driver. Change-Id: Ibf1796fcb99f288d4946b30e5e7225695aa61781 Reviewed-by: Gunnar Sletta --- src/corelib/animation/qabstractanimation.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 139876de3a..f7bb1e91bd 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -277,10 +277,12 @@ void QUnifiedTimer::updateAnimationTimers(qint64 currentTick) lastTick = totalElapsed; - //we make sure we only call update time if the time has actually changed - //it might happen in some cases that the time doesn't change because events are delayed - //when the CPU load is high - if (delta) { + //we make sure we only call update time if the time has actually advanced + //* it might happen in some cases that the time doesn't change because events are delayed + // when the CPU load is high + //* it might happen in some cases that the delta is negative because the animation driver + // advances faster than time.elapsed() + if (delta > 0) { insideTick = true; if (profilerCallback) profilerCallback(delta); -- cgit v1.2.3 From c2b2ef32ca523bc030aadc1cea524d4918b03c09 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 3 Apr 2014 17:03:36 +0200 Subject: Don't access null pointer Change-Id: If9ac712543f7c7fd85d877bba76e67ce89c60c61 Reviewed-by: Michael Brasser --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index d5c876624a..69601f44d4 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -665,9 +665,12 @@ void QXcbKeyboard::clearXKBConfig() void QXcbKeyboard::printKeymapError(const char *error) const { - qWarning() << error << "Current XKB configuration data search paths are: "; - for (unsigned int i = 0; i < xkb_context_num_include_paths(xkb_context); ++i) - qWarning() << xkb_context_include_path_get(xkb_context, i); + qWarning() << error; + if (xkb_context) { + qWarning() << "Current XKB configuration data search paths are: "; + for (unsigned int i = 0; i < xkb_context_num_include_paths(xkb_context); ++i) + qWarning() << xkb_context_include_path_get(xkb_context, i); + } qWarning() << "Use QT_XKB_CONFIG_ROOT environmental variable to provide an additional search path, " "add ':' as separator to provide several search paths and/or make sure that XKB configuration data " "directory contains recent enough contents, to update please see http://cgit.freedesktop.org/xkeyboard-config/ ."; -- cgit v1.2.3 From 6115ba4f4e30808fb48948fbc02f33b5de5ed9b3 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 4 Apr 2014 23:57:28 +0200 Subject: QPageSize: mark ctors explicit A QSize or QSizeF is not an accurate representation of a QPageSize, so the corresponding constructor should be explicit. Change-Id: I6b1808e5f93e3caef948c0e5300bd3c20e3c4210 Reviewed-by: Friedemann Kleint Reviewed-by: John Layt --- src/gui/painting/qpagesize.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpagesize.h b/src/gui/painting/qpagesize.h index c8a472747d..8b99d6af2e 100644 --- a/src/gui/painting/qpagesize.h +++ b/src/gui/painting/qpagesize.h @@ -230,12 +230,12 @@ public: QPageSize(); explicit QPageSize(QPageSize::PageSizeId pageSizeId); - QPageSize(const QSize &pointSize, - const QString &name = QString(), - QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch); - QPageSize(const QSizeF &size, QPageSize::Unit units, - const QString &name = QString(), - QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch); + explicit QPageSize(const QSize &pointSize, + const QString &name = QString(), + QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch); + explicit QPageSize(const QSizeF &size, QPageSize::Unit units, + const QString &name = QString(), + QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch); QPageSize(const QPageSize &other); ~QPageSize(); -- cgit v1.2.3 From 9f924338a8c003c01864a44569ed2fb4cbba7d2d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 4 Apr 2014 23:59:37 +0200 Subject: QPageSize: make op== non-member Better style, since it treats the left-hand and right-hand size symmetrically, e.g. for implicit conversions. Change-Id: If1ffa9dc2a018e402c884f60bfbc82e799daeb92 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/gui/painting/qpagesize.cpp | 13 ++++++++----- src/gui/painting/qpagesize.h | 4 +++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp index 7d19d49b4e..9cf7f192e8 100644 --- a/src/gui/painting/qpagesize.cpp +++ b/src/gui/painting/qpagesize.cpp @@ -1255,15 +1255,18 @@ QPageSize &QPageSize::operator=(const QPageSize &other) */ /*! - Returns \c true if this page is equal to the \a other page, i.e. if the - page has the same attributes. Current attributes are size and name. + \relates QPageSize + + Returns \c true if page size \a lhs is equal to page size \a rhs, + i.e. if the page sizes have the same attributes. Current + attributes are size and name. */ -bool QPageSize::operator==(const QPageSize &other) const +bool operator==(const QPageSize &lhs, const QPageSize &rhs) { - if (d == other.d) + if (lhs.d == rhs.d) return true; - return d && other.d && *d == *other.d; + return lhs.d && rhs.d && *lhs.d == *rhs.d; } /*! diff --git a/src/gui/painting/qpagesize.h b/src/gui/painting/qpagesize.h index 8b99d6af2e..d228f05a4a 100644 --- a/src/gui/painting/qpagesize.h +++ b/src/gui/painting/qpagesize.h @@ -246,7 +246,7 @@ public: void swap(QPageSize &other) { d.swap(other.d); } - bool operator==(const QPageSize &other) const; + friend Q_GUI_EXPORT bool operator==(const QPageSize &lhs, const QPageSize &rhs); bool isEquivalentTo(const QPageSize &other) const; bool isValid() const; @@ -298,6 +298,8 @@ private: Q_DECLARE_SHARED(QPageSize) +Q_GUI_EXPORT bool operator==(const QPageSize &lhs, const QPageSize &rhs); + #ifndef QT_NO_DEBUG_STREAM Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageSize &pageSize); #endif -- cgit v1.2.3 From 22afdaa2dadc9ef610cbb9c69755ca589fbf907b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Apr 2014 00:00:15 +0200 Subject: QPageSize: provide op!= For consistency. Change-Id: I4375a6f8c2514479a7479c735d397bf8a9876db1 Reviewed-by: Friedemann Kleint Reviewed-by: John Layt --- src/gui/painting/qpagesize.cpp | 8 ++++++++ src/gui/painting/qpagesize.h | 2 ++ tests/auto/gui/painting/qpagesize/tst_qpagesize.cpp | 3 +++ 3 files changed, 13 insertions(+) diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp index 9cf7f192e8..60ca69d1f2 100644 --- a/src/gui/painting/qpagesize.cpp +++ b/src/gui/painting/qpagesize.cpp @@ -1268,6 +1268,14 @@ bool operator==(const QPageSize &lhs, const QPageSize &rhs) return true; return lhs.d && rhs.d && *lhs.d == *rhs.d; } +/*! + \fn bool operator!=(const QPageSize &lhs, const QPageSize &rhs) + \relates QPageSize + + Returns \c true if page size \a lhs is unequal to page size \a + rhs, i.e. if the page size has different attributes. Current + attributes are size and name. +*/ /*! Returns \c true if this page is equivalent to the \a other page, i.e. if the diff --git a/src/gui/painting/qpagesize.h b/src/gui/painting/qpagesize.h index d228f05a4a..8205d2eae4 100644 --- a/src/gui/painting/qpagesize.h +++ b/src/gui/painting/qpagesize.h @@ -299,6 +299,8 @@ private: Q_DECLARE_SHARED(QPageSize) Q_GUI_EXPORT bool operator==(const QPageSize &lhs, const QPageSize &rhs); +inline bool operator!=(const QPageSize &lhs, const QPageSize &rhs) +{ return !operator==(lhs, rhs); } #ifndef QT_NO_DEBUG_STREAM Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageSize &pageSize); diff --git a/tests/auto/gui/painting/qpagesize/tst_qpagesize.cpp b/tests/auto/gui/painting/qpagesize/tst_qpagesize.cpp index 968c5ff617..c54f2350e5 100644 --- a/tests/auto/gui/painting/qpagesize/tst_qpagesize.cpp +++ b/tests/auto/gui/painting/qpagesize/tst_qpagesize.cpp @@ -137,10 +137,13 @@ void tst_QPageSize::basics() // Comparisons QCOMPARE((a4 == folio), false); + QCOMPARE((a4 != folio), true); QCOMPARE((a4.isEquivalentTo(folio)), false); QCOMPARE((a4 == a4b), true); + QCOMPARE((a4 != a4b), false); QCOMPARE((a4.isEquivalentTo(a4b)), true); QCOMPARE((folio == folio2), false); // Name different + QCOMPARE((folio != folio2), true); // Name different QCOMPARE((folio.isEquivalentTo(folio2)), true); // Simple QSize in Millimeters -- cgit v1.2.3 From 7b3d9bbdf22a2bed499fa1056ae1c66545c4f0cd Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Apr 2014 00:09:43 +0200 Subject: QPageLayout: remove QPageLayout:: overqualifications This is not Qt style, not needed, and clutters the code, so remove QPageLayout:: qualifications where they're not needed. Change-Id: I62f90c29bcb9f3c137d319051ac79e081fe5fb69 Reviewed-by: Friedemann Kleint Reviewed-by: John Layt --- src/gui/painting/qpagelayout.cpp | 32 ++++++++++++++++---------------- src/gui/painting/qpagelayout.h | 22 +++++++++++----------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp index 3f29a9d1f3..3da550a411 100644 --- a/src/gui/painting/qpagelayout.cpp +++ b/src/gui/painting/qpagelayout.cpp @@ -375,8 +375,8 @@ QPageLayout::QPageLayout() margins allowed by the page size. */ -QPageLayout::QPageLayout(const QPageSize &pageSize, QPageLayout::Orientation orientation, - const QMarginsF &margins, QPageLayout::Unit units, +QPageLayout::QPageLayout(const QPageSize &pageSize, Orientation orientation, + const QMarginsF &margins, Unit units, const QMarginsF &minMargins) : d(new QPageLayoutPrivate(pageSize, orientation, margins, units, minMargins)) { @@ -464,7 +464,7 @@ bool QPageLayout::isValid() const Sets a page layout mode to \a mode. */ -void QPageLayout::setMode(QPageLayout::Mode mode) +void QPageLayout::setMode(Mode mode) { d->m_mode = mode; } @@ -519,7 +519,7 @@ QPageSize QPageLayout::pageSize() const the minimum margins. */ -void QPageLayout::setOrientation(QPageLayout::Orientation orientation) +void QPageLayout::setOrientation(Orientation orientation) { if (orientation != d->m_orientation) { d->m_orientation = orientation; @@ -546,7 +546,7 @@ QPageLayout::Orientation QPageLayout::orientation() const Sets the \a units used to define the page layout. */ -void QPageLayout::setUnits(QPageLayout::Unit units) +void QPageLayout::setUnits(Unit units) { if (units != d->m_units) { d->m_margins = qt_convertMargins(d->m_margins, d->m_units, units); @@ -584,7 +584,7 @@ QPageLayout::Unit QPageLayout::units() const bool QPageLayout::setMargins(const QMarginsF &margins) { - if (d->m_mode == QPageLayout::FullPageMode) { + if (d->m_mode == FullPageMode) { d->m_margins = margins; return true; } else if (margins.left() >= d->m_minMargins.left() @@ -619,7 +619,7 @@ bool QPageLayout::setMargins(const QMarginsF &margins) bool QPageLayout::setLeftMargin(qreal leftMargin) { - if (d->m_mode == QPageLayout::FullPageMode + if (d->m_mode == FullPageMode || (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) { d->m_margins.setLeft(leftMargin); return true; @@ -645,7 +645,7 @@ bool QPageLayout::setLeftMargin(qreal leftMargin) bool QPageLayout::setRightMargin(qreal rightMargin) { - if (d->m_mode == QPageLayout::FullPageMode + if (d->m_mode == FullPageMode || (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) { d->m_margins.setRight(rightMargin); return true; @@ -671,7 +671,7 @@ bool QPageLayout::setRightMargin(qreal rightMargin) bool QPageLayout::setTopMargin(qreal topMargin) { - if (d->m_mode == QPageLayout::FullPageMode + if (d->m_mode == FullPageMode || (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) { d->m_margins.setTop(topMargin); return true; @@ -697,7 +697,7 @@ bool QPageLayout::setTopMargin(qreal topMargin) bool QPageLayout::setBottomMargin(qreal bottomMargin) { - if (d->m_mode == QPageLayout::FullPageMode + if (d->m_mode == FullPageMode || (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) { d->m_margins.setBottom(bottomMargin); return true; @@ -722,7 +722,7 @@ QMarginsF QPageLayout::margins() const \sa setMargins(), margins() */ -QMarginsF QPageLayout::margins(QPageLayout::Unit units) const +QMarginsF QPageLayout::margins(Unit units) const { return d->margins(units); } @@ -818,7 +818,7 @@ QRectF QPageLayout::fullRect() const \sa paintRect() */ -QRectF QPageLayout::fullRect(QPageLayout::Unit units) const +QRectF QPageLayout::fullRect(Unit units) const { return isValid() ? d->fullRect(units) : QRect(); } @@ -876,13 +876,13 @@ QRectF QPageLayout::paintRect() const the margins must be manually managed. */ -QRectF QPageLayout::paintRect(QPageLayout::Unit units) const +QRectF QPageLayout::paintRect(Unit units) const { if (!isValid()) return QRectF(); if (units == d->m_units) return d->paintRect(); - return d->m_mode == QPageLayout::FullPageMode ? d->fullRect(units) + return d->m_mode == FullPageMode ? d->fullRect(units) : d->fullRect(units) - d->margins(units); } @@ -900,7 +900,7 @@ QRect QPageLayout::paintRectPoints() const { if (!isValid()) return QRect(); - return d->m_mode == QPageLayout::FullPageMode ? d->fullRectPoints() + return d->m_mode == FullPageMode ? d->fullRectPoints() : d->fullRectPoints() - d->marginsPoints(); } @@ -918,7 +918,7 @@ QRect QPageLayout::paintRectPixels(int resolution) const { if (!isValid()) return QRect(); - return d->m_mode == QPageLayout::FullPageMode ? d->fullRectPixels(resolution) + return d->m_mode == FullPageMode ? d->fullRectPixels(resolution) : d->fullRectPixels(resolution) - d->marginsPixels(resolution); } diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h index 86e430e311..6e2752c3a1 100644 --- a/src/gui/painting/qpagelayout.h +++ b/src/gui/painting/qpagelayout.h @@ -79,8 +79,8 @@ public: }; QPageLayout(); - QPageLayout(const QPageSize &pageSize, QPageLayout::Orientation orientation, - const QMarginsF &margins, QPageLayout::Unit units = QPageLayout::Point, + QPageLayout(const QPageSize &pageSize, Orientation orientation, + const QMarginsF &margins, Unit units = Point, const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0)); QPageLayout(const QPageLayout &other); ~QPageLayout(); @@ -97,18 +97,18 @@ public: bool isValid() const; - void setMode(QPageLayout::Mode mode); - QPageLayout::Mode mode() const; + void setMode(Mode mode); + Mode mode() const; void setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0)); QPageSize pageSize() const; - void setOrientation(QPageLayout::Orientation orientation); - QPageLayout::Orientation orientation() const; + void setOrientation(Orientation orientation); + Orientation orientation() const; - void setUnits(QPageLayout::Unit units); - QPageLayout::Unit units() const; + void setUnits(Unit units); + Unit units() const; bool setMargins(const QMarginsF &margins); bool setLeftMargin(qreal leftMargin); @@ -117,7 +117,7 @@ public: bool setBottomMargin(qreal bottomMargin); QMarginsF margins() const; - QMarginsF margins(QPageLayout::Unit units) const; + QMarginsF margins(Unit units) const; QMargins marginsPoints() const; QMargins marginsPixels(int resolution) const; @@ -126,12 +126,12 @@ public: QMarginsF maximumMargins() const; QRectF fullRect() const; - QRectF fullRect(QPageLayout::Unit units) const; + QRectF fullRect(Unit units) const; QRect fullRectPoints() const; QRect fullRectPixels(int resolution) const; QRectF paintRect() const; - QRectF paintRect(QPageLayout::Unit units) const; + QRectF paintRect(Unit units) const; QRect paintRectPoints() const; QRect paintRectPixels(int resolution) const; -- cgit v1.2.3 From 0de0f494bd75786ff361da2ac05c85d8aeac3b37 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Apr 2014 00:51:43 +0200 Subject: QPageLayout: use QExplicitlySharedDataPointer Many setters check for an actual change before making changes to data members, but because of QSharedDataPointer, the detach had already happened by the time the comparison returned false. Change-Id: I320806e74de4a64fa3a340831621c1f5120ebb0f Reviewed-by: Friedemann Kleint Reviewed-by: John Layt --- src/gui/painting/qpagelayout.cpp | 11 +++++++++++ src/gui/painting/qpagelayout.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp index 3da550a411..5589a4364c 100644 --- a/src/gui/painting/qpagelayout.cpp +++ b/src/gui/painting/qpagelayout.cpp @@ -466,6 +466,7 @@ bool QPageLayout::isValid() const void QPageLayout::setMode(Mode mode) { + d.detach(); d->m_mode = mode; } @@ -494,6 +495,7 @@ void QPageLayout::setPageSize(const QPageSize &pageSize, const QMarginsF &minMar { if (!pageSize.isValid()) return; + d.detach(); d->m_pageSize = pageSize; d->m_fullSize = d->fullSizeUnits(d->m_units); d->setDefaultMargins(minMargins); @@ -522,6 +524,7 @@ QPageSize QPageLayout::pageSize() const void QPageLayout::setOrientation(Orientation orientation) { if (orientation != d->m_orientation) { + d.detach(); d->m_orientation = orientation; d->m_fullSize = d->fullSizeUnits(d->m_units); // Adust the max margins to reflect change in max page size @@ -549,6 +552,7 @@ QPageLayout::Orientation QPageLayout::orientation() const void QPageLayout::setUnits(Unit units) { if (units != d->m_units) { + d.detach(); d->m_margins = qt_convertMargins(d->m_margins, d->m_units, units); d->m_minMargins = qt_convertMargins(d->m_minMargins, d->m_units, units); d->m_maxMargins = qt_convertMargins(d->m_maxMargins, d->m_units, units); @@ -585,6 +589,7 @@ QPageLayout::Unit QPageLayout::units() const bool QPageLayout::setMargins(const QMarginsF &margins) { if (d->m_mode == FullPageMode) { + d.detach(); d->m_margins = margins; return true; } else if (margins.left() >= d->m_minMargins.left() @@ -595,6 +600,7 @@ bool QPageLayout::setMargins(const QMarginsF &margins) && margins.right() <= d->m_maxMargins.right() && margins.top() <= d->m_maxMargins.top() && margins.bottom() <= d->m_maxMargins.bottom()) { + d.detach(); d->m_margins = margins; return true; } @@ -621,6 +627,7 @@ bool QPageLayout::setLeftMargin(qreal leftMargin) { if (d->m_mode == FullPageMode || (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) { + d.detach(); d->m_margins.setLeft(leftMargin); return true; } @@ -647,6 +654,7 @@ bool QPageLayout::setRightMargin(qreal rightMargin) { if (d->m_mode == FullPageMode || (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) { + d.detach(); d->m_margins.setRight(rightMargin); return true; } @@ -673,6 +681,7 @@ bool QPageLayout::setTopMargin(qreal topMargin) { if (d->m_mode == FullPageMode || (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) { + d.detach(); d->m_margins.setTop(topMargin); return true; } @@ -699,6 +708,7 @@ bool QPageLayout::setBottomMargin(qreal bottomMargin) { if (d->m_mode == FullPageMode || (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) { + d.detach(); d->m_margins.setBottom(bottomMargin); return true; } @@ -764,6 +774,7 @@ QMargins QPageLayout::marginsPixels(int resolution) const void QPageLayout::setMinimumMargins(const QMarginsF &minMargins) { + d.detach(); d->setDefaultMargins(minMargins); } diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h index 6e2752c3a1..c636ca7476 100644 --- a/src/gui/painting/qpagelayout.h +++ b/src/gui/painting/qpagelayout.h @@ -137,7 +137,7 @@ public: private: friend class QPageLayoutPrivate; - QSharedDataPointer d; + QExplicitlySharedDataPointer d; }; Q_DECLARE_SHARED(QPageLayout) -- cgit v1.2.3 From 4bed03eb8515d090f476ed69be6331bb513ffaf7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 4 Apr 2014 23:59:37 +0200 Subject: QPageLayout: make op== non-member Better style, since it treats the left-hand and right-hand size symmetrically, e.g. for implicit conversions. Change-Id: Ib5d39b1ebffffcb664ee2f72c756702469e32d3b Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/gui/painting/qpagelayout.cpp | 14 ++++++++------ src/gui/painting/qpagelayout.h | 4 +++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp index 5589a4364c..b48b9f6e4d 100644 --- a/src/gui/painting/qpagelayout.cpp +++ b/src/gui/painting/qpagelayout.cpp @@ -424,21 +424,23 @@ QPageLayout &QPageLayout::operator=(const QPageLayout &other) */ /*! - Returns \c true if this page layout is equal to the \a other page layout, + \relates QPageLayout + + Returns \c true if page layout \a lhs is equal to page layout \a rhs, i.e. if all the attributes are exactly equal. Note that this is a strict equality, especially for page size where the QPageSize ID, name and size must exactly match, and the margins where the units must match. - \sa isEquivalentTo() + \sa QPageLayout::isEquivalentTo() */ -bool QPageLayout::operator==(const QPageLayout &other) const +bool operator==(const QPageLayout &lhs, const QPageLayout &rhs) { - if (d && other.d) - return (*d == *other.d); - return (d == other.d); + if (lhs.d && rhs.d) + return (*lhs.d == *rhs.d); + return (lhs.d == rhs.d); } /*! diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h index c636ca7476..0ca1682b20 100644 --- a/src/gui/painting/qpagelayout.h +++ b/src/gui/painting/qpagelayout.h @@ -92,7 +92,7 @@ public: void swap(QPageLayout &other) { d.swap(other.d); } - bool operator==(const QPageLayout &other) const; + friend Q_GUI_EXPORT bool operator==(const QPageLayout &lhs, const QPageLayout &rhs); bool isEquivalentTo(const QPageLayout &other) const; bool isValid() const; @@ -142,6 +142,8 @@ private: Q_DECLARE_SHARED(QPageLayout) +Q_GUI_EXPORT bool operator==(const QPageLayout &lhs, const QPageLayout &rhs); + #ifndef QT_NO_DEBUG_STREAM Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageLayout &pageLayout); #endif -- cgit v1.2.3 From c7dd6006b98536a80f02d96e660632ffa150934a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Apr 2014 00:00:15 +0200 Subject: QPageLayout: provide op!= For consistency. Change-Id: I20fb70999785e2c1947f033d63367a2f6746990a Reviewed-by: Friedemann Kleint Reviewed-by: John Layt --- src/gui/painting/qpagelayout.cpp | 14 ++++++++++++++ src/gui/painting/qpagelayout.h | 2 ++ tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp index b48b9f6e4d..d9e826bd64 100644 --- a/src/gui/painting/qpagelayout.cpp +++ b/src/gui/painting/qpagelayout.cpp @@ -443,6 +443,20 @@ bool operator==(const QPageLayout &lhs, const QPageLayout &rhs) return (lhs.d == rhs.d); } +/*! + \fn bool operator!=(const QPageLayout &lhs, const QPageLayout &rhs) + \relates QPageLayout + + Returns \c true if page layout \a lhs is not equal to page layout \a rhs, + i.e. if any of the attributes differ. + + Note that this is a strict equality, especially for page size where the + QPageSize ID, name and size must exactly match, and the margins where the + units must match. + + \sa QPageLayout::isEquivalentTo() +*/ + /*! Returns \c true if this page layout is equivalent to the \a other page layout, i.e. if the page has the same size, margins and orientation. diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h index 0ca1682b20..e63f6f4d39 100644 --- a/src/gui/painting/qpagelayout.h +++ b/src/gui/painting/qpagelayout.h @@ -143,6 +143,8 @@ private: Q_DECLARE_SHARED(QPageLayout) Q_GUI_EXPORT bool operator==(const QPageLayout &lhs, const QPageLayout &rhs); +inline bool operator!=(const QPageLayout &lhs, const QPageLayout &rhs) +{ return !operator==(lhs, rhs); } #ifndef QT_NO_DEBUG_STREAM Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageLayout &pageLayout); diff --git a/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp b/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp index 30d25f00d2..5f452b5602 100644 --- a/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp +++ b/tests/auto/gui/painting/qpagelayout/tst_qpagelayout.cpp @@ -83,8 +83,12 @@ void tst_QPageLayout::basics() QCOMPARE(simple.paintRectPoints(), QRect(0, 0, 595, 842)); QCOMPARE(simple.paintRectPixels(72), QRect(0, 0, 595, 842)); + const QPageLayout a4portrait = simple; + QVERIFY(a4portrait == simple); + // Change orientation simple.setOrientation(QPageLayout::Landscape); + QVERIFY(simple != a4portrait); QCOMPARE(simple.orientation(), QPageLayout::Landscape); QCOMPARE(simple.margins(), QMarginsF(0, 0, 0, 0)); QCOMPARE(simple.minimumMargins(), QMarginsF(0, 0, 0, 0)); -- cgit v1.2.3 From 1baf8e9ad723ebc8299ab360f585dd1a35946a97 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Apr 2014 01:07:39 +0200 Subject: QPageLayout: clean up operator== The old code always compared the Private classes, unless one of them was nullptr (which it never was, as there is no move ctor and all other ctors create a QPageLayoutPrivate. The new code compares the dpointers, and only if they differ, the Private classes. It also drops the nullptr checks, as they cannot trigger. Change-Id: I523c3503e2edb520f98f9b4e2e3bdaf28a9a355d Reviewed-by: Friedemann Kleint --- src/gui/painting/qpagelayout.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp index d9e826bd64..15d98828bf 100644 --- a/src/gui/painting/qpagelayout.cpp +++ b/src/gui/painting/qpagelayout.cpp @@ -438,9 +438,7 @@ QPageLayout &QPageLayout::operator=(const QPageLayout &other) bool operator==(const QPageLayout &lhs, const QPageLayout &rhs) { - if (lhs.d && rhs.d) - return (*lhs.d == *rhs.d); - return (lhs.d == rhs.d); + return lhs.d == rhs.d || *lhs.d == *rhs.d; } /*! -- cgit v1.2.3 From 6b2b0cd41b5a75f5a1f6e8c0313f2e9cce55e64e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Apr 2014 01:13:36 +0200 Subject: QPageSize: clean up operator== Recognize that the d-pointer can never be nullptr and drop the nullptr checks. The d-pointer can never be nullptr as there's no move ctor and all other ctors create a QPageSizePrivate. Change-Id: I6c4e165949ed55510aefbc2d933f20fc8e624333 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/gui/painting/qpagesize.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp index 60ca69d1f2..445c78e530 100644 --- a/src/gui/painting/qpagesize.cpp +++ b/src/gui/painting/qpagesize.cpp @@ -1264,9 +1264,7 @@ QPageSize &QPageSize::operator=(const QPageSize &other) bool operator==(const QPageSize &lhs, const QPageSize &rhs) { - if (lhs.d == rhs.d) - return true; - return lhs.d && rhs.d && *lhs.d == *rhs.d; + return lhs.d == rhs.d || *lhs.d == *rhs.d; } /*! \fn bool operator!=(const QPageSize &lhs, const QPageSize &rhs) -- cgit v1.2.3 From e14ef58f3d222004c82279be5461cde755b4239d Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Tue, 8 Apr 2014 14:59:37 +0200 Subject: Doc: Add a section all modules can use for example documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -modules that use the qt-module-defaults.qdocconf have access to the .qdocinc file. -content about running examples can be used by example documentation. Task-number: QTBUG-33597 Change-Id: I88d93a9982c05a24b4f7ac1b2cfb3293e56031b2 Reviewed-by: Topi Reiniö Reviewed-by: Leena Miettinen --- doc/global/config.qdocconf | 2 ++ doc/global/includes/examples-run.qdocinc | 5 +++++ 2 files changed, 7 insertions(+) create mode 100644 doc/global/includes/examples-run.qdocinc diff --git a/doc/global/config.qdocconf b/doc/global/config.qdocconf index 8629b89e7e..670b13a9ea 100644 --- a/doc/global/config.qdocconf +++ b/doc/global/config.qdocconf @@ -10,3 +10,5 @@ dita.metadata.default.audience = programmer #Set the main Qt index.html navigation.homepage = "Qt $QT_VER" buildversion = "Qt $QT_VERSION Reference Documentation" + +sourcedirs += includes diff --git a/doc/global/includes/examples-run.qdocinc b/doc/global/includes/examples-run.qdocinc new file mode 100644 index 0000000000..e9b8575650 --- /dev/null +++ b/doc/global/includes/examples-run.qdocinc @@ -0,0 +1,5 @@ +\section1 Running the Example + +To run the example from \l{Qt Creator Manual}{Qt Creator}, open the \gui Welcome +mode and select the example from \gui Examples. For more information, visit +\l{Qt Creator: Building and Running an Example}{Building and Running an Example}. -- cgit v1.2.3 From e215aba4aa604e534b0ab9c50400da5d4d4e49ae Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Tue, 8 Apr 2014 22:26:24 +0200 Subject: XCB: Only use the XFixes extension if available Commit 0d4918950e61f added a new place (QXcbWindow::setTransparentForMouseEvents()) where requests from the XFixes extension are generated. However, this wasn't checking if the extension is actually supported before using it. Fix this by turning QXcbWindow::setTransparentForMouseEvents() into a no-op if the XFixes extension isn't available. This means that the window in question won't be transparent for mouse events, but we cannot do much about that if the X server doesn't support the required extension. Task-number: QTBUG-38109 Change-Id: I2931481eb71bab990f2dcf0ec600b9e62d3d799c Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index bed6eb59dc..5a2002f1d4 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1174,7 +1174,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp) void QXcbWindow::setTransparentForMouseEvents(bool transparent) { - if (transparent == m_transparent) + if (!connection()->hasXFixes() || transparent == m_transparent) return; xcb_rectangle_t rectangle; -- cgit v1.2.3 From 7d012552b03cd71a44591adf1e148b7b5eab0431 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 31 Mar 2014 11:24:43 +0200 Subject: Add diagnostic output to tst_QtConcurrentIterateKernel. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add messages to comparisons and expect failure of blockSize() on Windows. Task-number: QTBUG-37822 Change-Id: Ie71d35a3d1ba0e52c93d5ba3fd7e92465b170d49 Reviewed-by: Morten Johan Sørvig --- .../tst_qtconcurrentiteratekernel.cpp | 42 +++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp index 33133e876f..1ca900fa27 100644 --- a/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp +++ b/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp @@ -151,7 +151,9 @@ void tst_QtConcurrentIterateKernel::cancel() f.cancel(); f.waitForFinished(); QVERIFY(f.isCanceled()); - QVERIFY(iterations.load() <= QThread::idealThreadCount()); // the threads might run one iteration each before they are canceled. + // the threads might run one iteration each before they are canceled. + QVERIFY2(iterations.load() <= QThread::idealThreadCount(), + (QByteArray::number(iterations.load()) + ' ' + QByteArray::number(QThread::idealThreadCount()))); } } @@ -251,26 +253,48 @@ void tst_QtConcurrentIterateKernel::throttling() QCOMPARE(threads.count(), 1); } - -int peakBlockSize = 0; class BlockSizeRecorder : public IterateKernel { public: - BlockSizeRecorder(TestIterator begin, TestIterator end) : IterateKernel(begin, end) { } + BlockSizeRecorder(TestIterator begin, TestIterator end) + : IterateKernel(begin, end) + , peakBlockSize(0) + , peakBegin(0) + {} + inline bool runIterations(TestIterator, int begin, int end, void *) { - peakBlockSize = qMax(peakBlockSize, end - begin); + const int blockSize = end - begin; + if (blockSize > peakBlockSize) { + peakBlockSize = blockSize; + peakBegin = begin; + } return false; } + int peakBlockSize; + int peakBegin; }; +static QByteArray msgBlockSize(const BlockSizeRecorder &recorder, int expectedMinimumBlockSize) +{ + return QByteArrayLiteral("peakBlockSize=") + QByteArray::number(recorder.peakBlockSize) + + QByteArrayLiteral(" is less than expectedMinimumBlockSize=") + + QByteArray::number(expectedMinimumBlockSize) + + QByteArrayLiteral(", reached at: ") + QByteArray::number(recorder.peakBegin) + + QByteArrayLiteral(" (ideal thread count: ") + QByteArray::number(QThread::idealThreadCount()) + + ')'; +} + void tst_QtConcurrentIterateKernel::blockSize() { const int expectedMinimumBlockSize = 1024 / QThread::idealThreadCount(); - BlockSizeRecorder(0, 10000).startBlocking(); - if (peakBlockSize < expectedMinimumBlockSize) - qDebug() << "block size" << peakBlockSize; - QVERIFY(peakBlockSize >= expectedMinimumBlockSize); + BlockSizeRecorder recorder(0, 10000); + recorder.startBlocking(); +#ifdef Q_OS_WIN + if (recorder.peakBlockSize < expectedMinimumBlockSize) + QEXPECT_FAIL("", msgBlockSize(recorder, expectedMinimumBlockSize).constData(), Abort); +#endif // Q_OS_WIN + QVERIFY2(recorder.peakBlockSize >= expectedMinimumBlockSize, msgBlockSize(recorder, expectedMinimumBlockSize)); } class MultipleResultsFor : public IterateKernel -- cgit v1.2.3 From 041c4d9c0bbb19dfa18ec304b5111259b0a48023 Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Wed, 8 Jan 2014 21:58:16 +0100 Subject: Forward "_q_platform_*" QWidgets's properties to QWindow. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way we can customize QPlatformWindow by using dynamic "_q_platform_" properties in corresponding QWindow. Change-Id: I987b7a17d252541fe766af6aa37a6cffb67f1807 Reviewed-by: Gabriel de Dietrich Reviewed-by: Morten Johan Sørvig Reviewed-by: Andy Shaw --- src/widgets/kernel/qwidget.cpp | 2 ++ src/widgets/kernel/qwidget_qpa.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 5bcec13238..7eecd3d84d 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8358,6 +8358,8 @@ bool QWidget::event(QEvent *event) d->extra->customDpiY = value; d->updateFont(d->data.fnt); } + if (windowHandle() && !qstrncmp(propName, "_q_platform_", 12)) + windowHandle()->setProperty(propName, property(propName)); // fall through } #endif diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index c22320e8d2..5ba0a90d3d 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -110,6 +110,11 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO win = topData()->window; } + foreach (const QByteArray &propertyName, q->dynamicPropertyNames()) { + if (!qstrncmp(propertyName, "_q_platform_", 12)) + win->setProperty(propertyName, q->property(propertyName)); + } + win->setFlags(data.window_flags); fixPosIncludesFrame(); if (q->testAttribute(Qt::WA_Moved) -- cgit v1.2.3 From 7537a4605ad65a039f5e9812939a13fbf7656e29 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 8 Apr 2014 17:32:26 +0200 Subject: Correct QOpenGLContext::versionFunctions() docs The example is incorrect: no context parameter is needed. There was also no mentioning of the fact the the context must be current at the time of calling initializeOpenGLFunctions(). This is corrected too. Change-Id: If8695140096e4b4f84927579c099b0af80750703 Reviewed-by: Sean Harmer --- src/gui/kernel/qopenglcontext.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 7a901a2877..7382d63a06 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -617,7 +617,8 @@ QOpenGLFunctions *QOpenGLContext::functions() const Returns a pointer to an object that provides access to all functions for the version and profile of this context. Before using any of the functions - they must be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions(). + they must be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions() + with this context being the current context. Usually one would use the template version of this function to automatically have the result cast to the correct type. @@ -629,7 +630,7 @@ QOpenGLFunctions *QOpenGLContext::functions() const qWarning() << "Could not obtain required OpenGL context version"; exit(1); } - funcs->initializeOpenGLFunctions(context); + funcs->initializeOpenGLFunctions(); \endcode It is possible to request a functions object for a different version and profile @@ -659,8 +660,9 @@ QOpenGLFunctions *QOpenGLContext::functions() const /*! Returns a pointer to an object that provides access to all functions for the - \a versionProfile of the current context. Before using any of the functions they must - be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions(). + \a versionProfile of this context. Before using any of the functions they must + be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions() + with this context being the current context. Usually one would use the template version of this function to automatically have the result cast to the correct type. -- cgit v1.2.3 From ccdfe354a64d145fc457d123c5d9b0bf15575738 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 20 Mar 2014 16:38:36 +0100 Subject: Accessibility Mac: Cache Accessible Elements and Notify about changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The big change is that we now keep the id objects representing accessibles around so that they are persistent for ATs. This improves performance of Mac accessibility significantly. This is required for notifications which are now sent so that many things work much better, for example the VoiceOver focus follows the keyboard focus. The parent element in QCocoaAccessibleElement was removed, we can dynamically access it more reliably. Change-Id: I686d212f40d28b392dcc22f16f3c3430f08bdc98 Reviewed-by: Morten Johan Sørvig --- src/gui/accessible/accessible.pri | 2 + src/gui/accessible/qaccessible.cpp | 28 +++--- src/gui/accessible/qaccessiblecache.cpp | 13 ++- src/gui/accessible/qaccessiblecache_mac.mm | 67 +++++++++++++ src/gui/accessible/qaccessiblecache_p.h | 29 +++++- src/plugins/platforms/cocoa/qcocoaaccessibility.h | 2 +- src/plugins/platforms/cocoa/qcocoaaccessibility.mm | 43 ++++++--- .../platforms/cocoa/qcocoaaccessibilityelement.h | 5 +- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 96 +++++++++++++----- .../platforms/cocoa/qnsviewaccessibility.mm | 3 +- tests/auto/other/other.pro | 1 + .../qaccessibilitymac/tst_qaccessibilitymac.cpp | 13 ++- .../tst_qaccessibilitymac_helpers.h | 6 +- .../tst_qaccessibilitymac_helpers.mm | 107 +++++++++++++++++++-- 14 files changed, 342 insertions(+), 73 deletions(-) create mode 100644 src/gui/accessible/qaccessiblecache_mac.mm diff --git a/src/gui/accessible/accessible.pri b/src/gui/accessible/accessible.pri index 615323dbec..86ed4c3a71 100644 --- a/src/gui/accessible/accessible.pri +++ b/src/gui/accessible/accessible.pri @@ -16,4 +16,6 @@ contains(QT_CONFIG, accessibility) { HEADERS += accessible/qaccessiblebridge.h SOURCES += accessible/qaccessiblebridge.cpp + + OBJECTIVE_SOURCES += accessible/qaccessiblecache_mac.mm } diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index dffdfa889a..776320a517 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -591,8 +591,6 @@ QAccessible::RootObjectHandler QAccessible::installRootObjectHandler(RootObjectH return old; } -Q_GLOBAL_STATIC(QAccessibleCache, qAccessibleCache) - /*! If a QAccessibleInterface implementation exists for the given \a object, this function returns a pointer to the implementation; otherwise it @@ -616,8 +614,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object) if (!object) return 0; - if (Id id = qAccessibleCache->objectToId.value(object)) - return qAccessibleCache->interfaceForId(id); + if (Id id = QAccessibleCache::instance()->objectToId.value(object)) + return QAccessibleCache::instance()->interfaceForId(id); // Create a QAccessibleInterface for the object class. Start by the most // derived class and walk up the class hierarchy. @@ -629,8 +627,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object) for (int i = qAccessibleFactories()->count(); i > 0; --i) { InterfaceFactory factory = qAccessibleFactories()->at(i - 1); if (QAccessibleInterface *iface = factory(cn, object)) { - qAccessibleCache->insert(object, iface); - Q_ASSERT(qAccessibleCache->objectToId.contains(object)); + QAccessibleCache::instance()->insert(object, iface); + Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(object)); return iface; } } @@ -652,8 +650,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object) if (factory) { QAccessibleInterface *result = factory->create(cn, object); if (result) { // Need this condition because of QDesktopScreenWidget - qAccessibleCache->insert(object, result); - Q_ASSERT(qAccessibleCache->objectToId.contains(object)); + QAccessibleCache::instance()->insert(object, result); + Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(object)); } return result; } @@ -665,8 +663,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object) #ifndef QT_NO_ACCESSIBILITY if (object == qApp) { QAccessibleInterface *appInterface = new QAccessibleApplication; - qAccessibleCache->insert(object, appInterface); - Q_ASSERT(qAccessibleCache->objectToId.contains(qApp)); + QAccessibleCache::instance()->insert(object, appInterface); + Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(qApp)); return appInterface; } #endif @@ -691,7 +689,7 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object) QAccessible::Id QAccessible::registerAccessibleInterface(QAccessibleInterface *iface) { Q_ASSERT(iface); - return qAccessibleCache->insert(iface->object(), iface); + return QAccessibleCache::instance()->insert(iface->object(), iface); } /*! @@ -701,7 +699,7 @@ QAccessible::Id QAccessible::registerAccessibleInterface(QAccessibleInterface *i */ void QAccessible::deleteAccessibleInterface(Id id) { - qAccessibleCache->deleteInterface(id); + QAccessibleCache::instance()->deleteInterface(id); } /*! @@ -709,7 +707,7 @@ void QAccessible::deleteAccessibleInterface(Id id) */ QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface) { - Id id = qAccessibleCache->idToInterface.key(iface); + Id id = QAccessibleCache::instance()->idToInterface.key(iface); if (!id) id = registerAccessibleInterface(iface); return id; @@ -722,7 +720,7 @@ QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface) */ QAccessibleInterface *QAccessible::accessibleInterface(Id id) { - return qAccessibleCache->idToInterface.value(id); + return QAccessibleCache::instance()->idToInterface.value(id); } diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp index fe66c6e19d..09c155515e 100644 --- a/src/gui/accessible/qaccessiblecache.cpp +++ b/src/gui/accessible/qaccessiblecache.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -49,6 +49,13 @@ QT_BEGIN_NAMESPACE \brief Maintains a cache of accessible interfaces. */ +Q_GLOBAL_STATIC(QAccessibleCache, qAccessibleCache) + +QAccessibleCache *QAccessibleCache::instance() +{ + return qAccessibleCache; +} + /* The ID is always in the range [INT_MAX+1, UINT_MAX]. This makes it easy on windows to reserve the positive integer range @@ -113,6 +120,10 @@ void QAccessibleCache::deleteInterface(QAccessible::Id id, QObject *obj) if (obj) objectToId.remove(obj); delete iface; + +#ifdef Q_OS_MACX + removeCocoaElement(id); +#endif } QT_END_NAMESPACE diff --git a/src/gui/accessible/qaccessiblecache_mac.mm b/src/gui/accessible/qaccessiblecache_mac.mm new file mode 100644 index 0000000000..861423af7d --- /dev/null +++ b/src/gui/accessible/qaccessiblecache_mac.mm @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qaccessiblecache_p.h" + +#ifdef Q_OS_OSX + +QT_BEGIN_NAMESPACE + +void QAccessibleCache::insertElement(QAccessible::Id axid, QCocoaAccessibleElement *element) const +{ + cocoaElements[axid] = element; +} + +void QAccessibleCache::removeCocoaElement(QAccessible::Id axid) +{ + QCocoaAccessibleElement *element = elementForId(axid); + [element invalidate]; + cocoaElements.remove(axid); +} + +QCocoaAccessibleElement *QAccessibleCache::elementForId(QAccessible::Id axid) const +{ + return cocoaElements.value(axid); +} + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/accessible/qaccessiblecache_p.h b/src/gui/accessible/qaccessiblecache_p.h index 32f9c443ba..30b023cfbd 100644 --- a/src/gui/accessible/qaccessiblecache_p.h +++ b/src/gui/accessible/qaccessiblecache_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -42,24 +42,42 @@ #ifndef QACCESSIBLECACHE_P #define QACCESSIBLECACHE_P +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include #include #include #include "qaccessible.h" -QT_BEGIN_NAMESPACE +Q_FORWARD_DECLARE_OBJC_CLASS(QCocoaAccessibleElement); +QT_BEGIN_NAMESPACE -class QAccessibleCache :public QObject +class Q_GUI_EXPORT QAccessibleCache :public QObject { Q_OBJECT public: + static QAccessibleCache *instance(); QAccessibleInterface *interfaceForId(QAccessible::Id id) const; QAccessible::Id insert(QObject *object, QAccessibleInterface *iface) const; void deleteInterface(QAccessible::Id id, QObject *obj = 0); +#ifdef Q_OS_OSX + QCocoaAccessibleElement *elementForId(QAccessible::Id axid) const; + void insertElement(QAccessible::Id axid, QCocoaAccessibleElement *element) const; +#endif + private Q_SLOTS: void objectDestroyed(QObject *obj); @@ -69,6 +87,11 @@ private: mutable QHash idToInterface; mutable QHash objectToId; +#ifdef Q_OS_OSX + void removeCocoaElement(QAccessible::Id axid); + mutable QHash cocoaElements; +#endif + friend class QAccessible; friend class QAccessibleInterface; }; diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h index 86bb5323a7..a78901bfb1 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h @@ -79,7 +79,7 @@ namespace QCocoaAccessible { NSString *macRole(QAccessibleInterface *interface); bool shouldBeIgnored(QAccessibleInterface *interface); -NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface); +NSArray *unignoredChildren(QAccessibleInterface *interface); NSString *getTranslatedAction(const QString &qtAction); NSMutableArray *createTranslatedActionsList(const QStringList &qtActions); QString translateAction(NSString *nsAction); diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 990acd5301..72045a1bbb 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -55,19 +55,31 @@ QCocoaAccessibility::~QCocoaAccessibility() void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) { - QAccessible::Id interfaceId = event->uniqueId(); - if (!interfaceId) + QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithId: event->uniqueId()]; + if (!element) { + qWarning() << "QCocoaAccessibility::notifyAccessibilityUpdate: invalid element"; return; + } switch (event->type()) { - case QAccessible::ValueChanged: - case QAccessible::TextInserted : - case QAccessible::TextRemoved : - case QAccessible::TextUpdated : { - QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId : interfaceId parent : nil]; - [element autorelease]; - NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification); - break; } + case QAccessible::Focus: { + NSAccessibilityPostNotification(element, NSAccessibilityFocusedUIElementChangedNotification); + break; + } + case QAccessible::StateChanged: + case QAccessible::ValueChanged: + case QAccessible::TextInserted: + case QAccessible::TextRemoved: + case QAccessible::TextUpdated: + NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification); + break; + case QAccessible::TextCaretMoved: + case QAccessible::TextSelectionChanged: + NSAccessibilityPostNotification(element, NSAccessibilitySelectedTextChangedNotification); + break; + case QAccessible::NameChanged: + NSAccessibilityPostNotification(element, NSAccessibilityTitleChangedNotification); + break; default: break; } @@ -218,7 +230,7 @@ bool shouldBeIgnored(QAccessibleInterface *interface) return false; } -NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface) +NSArray *unignoredChildren(QAccessibleInterface *interface) { int numKids = interface->childCount(); // qDebug() << "Children for: " << axid << iface << " are: " << numKids; @@ -231,9 +243,12 @@ NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface) QAccessible::Id childId = QAccessible::uniqueId(child); //qDebug() << " kid: " << childId << child; - QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId:childId parent:parentObject]; - [kids addObject: element]; - [element release]; + + QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithId: childId]; + if (element) + [kids addObject: element]; + else + qWarning() << "QCocoaAccessibility: invalid child"; } return NSAccessibilityUnignoredChildren(kids); } diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h index c207cbee2d..babaab5ae2 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h @@ -52,12 +52,11 @@ @interface QCocoaAccessibleElement : NSObject { NSString *role; - NSObject *parent; QAccessible::Id axid; } -- (id)initWithId:(QAccessible::Id)anId parent:(id)aParent; -+ (QCocoaAccessibleElement *)createElementWithId:(QAccessible::Id)anId parent:(id)aParent; +- (id)initWithId:(QAccessible::Id)anId; ++ (QCocoaAccessibleElement *)elementWithId:(QAccessible::Id)anId; @end diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index d9bfdbd55d..1df4230385 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -41,6 +41,8 @@ #include "qcocoaaccessibilityelement.h" #include "qcocoaaccessibility.h" #include "qcocoahelpers.h" +#include "qcocoawindow.h" +#include "private/qaccessiblecache_p.h" #include @@ -48,7 +50,7 @@ @implementation QCocoaAccessibleElement -- (id)initWithId:(QAccessible::Id)anId parent:(id)aParent +- (id)initWithId:(QAccessible::Id)anId { Q_ASSERT((int)anId < 0); self = [super init]; @@ -57,15 +59,35 @@ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); Q_ASSERT(iface); role = QCocoaAccessible::macRole(iface); - parent = aParent; } return self; } -+ (QCocoaAccessibleElement *)createElementWithId:(QAccessible::Id)anId parent:(id)aParent ++ (id)elementWithId:(QAccessible::Id)anId { - return [[self alloc] initWithId:anId parent:aParent]; + Q_ASSERT(anId); + if (!anId) + return nil; + + QAccessibleCache *cache = QAccessibleCache::instance(); + + QCocoaAccessibleElement *element = cache->elementForId(anId); + if (!element) { + QAccessibleInterface *iface = QAccessible::accessibleInterface(anId); + Q_ASSERT(iface); + if (!iface) + return nil; + element = [[self alloc] initWithId:anId]; + cache->insertElement(anId, element); + } + return element; +} + +- (void)invalidate { + axid = 0; + NSAccessibilityPostNotification(self, NSAccessibilityUIElementDestroyedNotification); + [self release]; } - (void)dealloc { @@ -98,6 +120,10 @@ return [NSNumber numberWithInt: newlines]; } +- (BOOL) accessibilityNotifiesWhenDestroyed { + return YES; +} + - (NSArray *)accessibilityAttributeNames { static NSArray *defaultAttributes = nil; @@ -145,6 +171,26 @@ return [attributes autorelease]; } +- (id)parentElement { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface) + return nil; + + if (QWindow *window = iface->window()) { + QCocoaWindow *win = static_cast(window->handle()); + return win->qtView(); + } + + QAccessibleInterface *parent = iface->parent(); + if (!parent) { + qWarning() << "INVALID PARENT FOR INTERFACE: " << iface; + return nil; + } + + QAccessible::Id parentId = QAccessible::uniqueId(parent); + return [QCocoaAccessibleElement elementWithId: parentId]; +} + - (id)accessibilityAttributeValue:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); if (!iface) { @@ -157,19 +203,19 @@ } else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { return NSAccessibilityRoleDescription(role, nil); } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { - return QCocoaAccessible::unignoredChildren(self, iface); + return QCocoaAccessible::unignoredChildren(iface); } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { // Just check if the app thinks we're focused. id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute]; return [NSNumber numberWithBool:[focusedElement isEqual:self]]; } else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) { - return NSAccessibilityUnignoredAncestor(parent); + return NSAccessibilityUnignoredAncestor([self parentElement]); } else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) { // We're in the same window as our parent. - return [parent accessibilityAttributeValue:NSAccessibilityWindowAttribute]; + return [[self parentElement] accessibilityAttributeValue:NSAccessibilityWindowAttribute]; } else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) { // We're in the same top level element as our parent. - return [parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; + return [[self parentElement] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; } else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { QPoint qtPosition = iface->rect().topLeft(); QSize qtSize = iface->rect().size(); @@ -403,20 +449,26 @@ return NSAccessibilityUnignoredAncestor(self); } - QAccessibleInterface *childInterface = iface->childAt(point.x, qt_mac_flipYCoordinate(point.y)); - + int y = qt_mac_flipYCoordinate(point.y); + QAccessibleInterface *childInterface = iface->childAt(point.x, y); // No child found, meaning we hit this element. - if (!childInterface) { -// qDebug() << "Hit test returns: " << id << iface; + if (!childInterface) return NSAccessibilityUnignoredAncestor(self); - } + + // find the deepest child at the point + QAccessibleInterface *childOfChildInterface = 0; + do { + childOfChildInterface = childInterface->childAt(point.x, y); + if (childOfChildInterface) + childInterface = childOfChildInterface; + } while (childOfChildInterface); QAccessible::Id childId = QAccessible::uniqueId(childInterface); // hit a child, forward to child accessible interface. - QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childId parent:self]; - [accessibleElement autorelease]; - - return [accessibleElement accessibilityHitTest:point]; + QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithId:childId]; + if (accessibleElement) + return NSAccessibilityUnignoredAncestor(accessibleElement); + return NSAccessibilityUnignoredAncestor(self); } - (id)accessibilityFocusedUIElement { @@ -426,17 +478,15 @@ qWarning() << "FocusedUIElement for INVALID"; return nil; } + QAccessibleInterface *childInterface = iface->focusChild(); if (childInterface) { QAccessible::Id childAxid = QAccessible::uniqueId(childInterface); - // FIXME: parent could be wrong - QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self]; - [accessibleElement autorelease]; - return accessibleElement; + QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithId:childAxid]; + return NSAccessibilityUnignoredAncestor(accessibleElement); } - // no focus found - return nil; + return NSAccessibilityUnignoredAncestor(self); } @end diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm index 31e3e343b9..d18a01b11c 100644 --- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm +++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm @@ -59,8 +59,7 @@ return nil; QAccessible::Id childId = QAccessible::uniqueId(m_window->accessibleRoot()); - QCocoaAccessibleElement *child = [QCocoaAccessibleElement createElementWithId: childId parent: self]; - return [child autorelease]; + return [QCocoaAccessibleElement elementWithId: childId]; } // The QNSView is a container that the user does not interact directly with: diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index f7f22fd71e..e6017168d0 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -16,6 +16,7 @@ SUBDIRS=\ networkselftest \ qaccessibility \ qaccessibilitylinux \ + qaccessibilitymac \ qcomplextext \ qfocusevent \ qnetworkaccessmanager_and_qprogressdialog \ diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac.cpp b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac.cpp index 25b47ee836..f521b64bed 100644 --- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac.cpp +++ b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -82,6 +82,8 @@ private slots: void singleWidgetTest(); void lineEditTest(); void hierarchyTest(); + void notificationsTest(); + private: AccessibleTestWindow *m_window; }; @@ -123,6 +125,7 @@ void tst_QAccessibilityMac::lineEditTest() m_window->addWidget(lineEdit); QVERIFY(QTest::qWaitForWindowExposed(m_window)); QCoreApplication::processEvents(); + QVERIFY(testLineEdit()); } @@ -148,5 +151,13 @@ void tst_QAccessibilityMac::hierarchyTest() QVERIFY(testHierarchy(w)); } +void tst_QAccessibilityMac::notificationsTest() +{ + if (!macNativeAccessibilityEnabled()) + return; + + QVERIFY(notifications(m_window)); +} + QTEST_MAIN(tst_QAccessibilityMac) #include "tst_qaccessibilitymac.moc" diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.h b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.h index 635b6383ab..818cabb000 100644 --- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.h +++ b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -42,11 +42,13 @@ #include #include - #pragma once // Yeah, it's deprecated in general, but it's standard practice for Mac OS X. +QT_USE_NAMESPACE + bool macNativeAccessibilityEnabled(); bool trusted(); bool testLineEdit(); bool testHierarchy(QWidget *w); bool singleWidget(); +bool notifications(QWidget *w); diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm index bc89ac858b..a0dfe5446e 100644 --- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm +++ b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -46,12 +46,15 @@ #include #include #include +#include #include #include #import #import +QT_USE_NAMESPACE + bool macNativeAccessibilityEnabled() { bool enabled = AXAPIEnabled(); @@ -76,6 +79,10 @@ bool trusted() @interface TestAXObject : NSObject { AXUIElementRef reference; + NSString *_role; + NSString *_description; + NSString *_value; + CGRect _rect; } @property (readonly) NSString *role; @property (readonly) NSString *description; @@ -84,7 +91,14 @@ bool trusted() @end @implementation TestAXObject + + @synthesize role = _role; + @synthesize description = _description; + @synthesize value = _value; + @synthesize rect = _rect; + - (id) initWithAXUIElementRef: (AXUIElementRef) ref { + if ( self = [super init] ) { reference = ref; AXUIElementCopyAttributeValue(ref, kAXRoleAttribute, (CFTypeRef*)&_role); @@ -103,7 +117,7 @@ bool trusted() - (AXUIElementRef) ref { return reference; } - (void) print { NSLog(@"Accessible Object role: '%@', description: '%@', value: '%@', rect: '%@'", self.role, self.description, self.value, NSStringFromRect(self.rect)); - NSLog(@" Children: %ld", [self.childList count]); + NSLog(@" Children: %ld", [[self childList] count]); } - (NSArray*) windowList @@ -163,10 +177,10 @@ bool trusted() bool singleWidget() { - QLineEdit le; - le.setText("button"); - le.show(); - EXPECT(QTest::qWaitForWindowExposed(&le)); + QLineEdit *le = new QLineEdit(); + le->setText("button"); + le->show(); + EXPECT(QTest::qWaitForWindowExposed(le)); QCoreApplication::processEvents(); TestAXObject *appObject = [TestAXObject getApplicationAXObject]; @@ -179,8 +193,16 @@ bool singleWidget() EXPECT(windowRef != nil); TestAXObject *window = [[TestAXObject alloc] initWithAXUIElementRef: windowRef]; - AXUIElementRef lineEdit = [window findDirectChildByRole: kAXTextFieldRole]; - EXPECT(lineEdit != nil); + AXUIElementRef lineEditRef = [window findDirectChildByRole: kAXTextFieldRole]; + EXPECT(lineEditRef != nil); + TestAXObject *lineEdit = [[TestAXObject alloc] initWithAXUIElementRef: lineEditRef]; + EXPECT([[lineEdit value] isEqualToString:@"button"]); + + // Access invalid reference, should return empty value + delete le; + QCoreApplication::processEvents(); + TestAXObject *lineEditInvalid = [[TestAXObject alloc] initWithAXUIElementRef: lineEditRef]; + EXPECT([[lineEditInvalid value] length] == 0); return true; } @@ -207,6 +229,10 @@ bool testLineEdit() // height of window includes title bar EXPECT([window rect].size.height >= 400); + NSString *windowTitle; + AXUIElementCopyAttributeValue(windowRef, kAXTitleAttribute, (CFTypeRef*)&windowTitle); + EXPECT([windowTitle isEqualToString:@"Test window"]); + // children of window: AXUIElementRef lineEdit = [window findDirectChildByRole: kAXTextFieldRole]; EXPECT(lineEdit != nil); @@ -270,3 +296,68 @@ bool testHierarchy(QWidget *w) return true; } + +QVector notificationList; + +void observerCallback(AXObserverRef /*observer*/, AXUIElementRef /*element*/, CFStringRef notification, void *) +{ + if ([(NSString*)notification isEqualToString: NSAccessibilityFocusedUIElementChangedNotification]) + notificationList.append(QAccessible::Focus); + else if ([(NSString*)notification isEqualToString: NSAccessibilityValueChangedNotification]) + notificationList.append(QAccessible::ValueChanged); + else + notificationList.append(-1); +} + + +bool notifications(QWidget *w) +{ + QLineEdit *le1 = new QLineEdit(w); + QLineEdit *le2 = new QLineEdit(w); + w->layout()->addWidget(le1); + w->layout()->addWidget(le2); + + QCoreApplication::processEvents(); + QTest::qWait(100); + + TestAXObject *appObject = [TestAXObject getApplicationAXObject]; + EXPECT(appObject); + + NSArray *windowList = [appObject windowList]; + // one window + EXPECT([windowList count] == 1); + AXUIElementRef windowRef = (AXUIElementRef) [windowList objectAtIndex: 0]; + EXPECT(windowRef != nil); + TestAXObject *window = [[TestAXObject alloc] initWithAXUIElementRef: windowRef]; + + AXUIElementRef lineEdit1 = [window findDirectChildByRole: kAXTextFieldRole]; + EXPECT(lineEdit1 != nil); + + AXObserverRef observer = 0; + AXError err = AXObserverCreate(getpid(), observerCallback, &observer); + EXPECT(!err); + AXObserverAddNotification(observer, appObject.ref, kAXFocusedUIElementChangedNotification, 0); + AXObserverAddNotification(observer, lineEdit1, kAXValueChangedNotification, 0); + + CFRunLoopAddSource( [[NSRunLoop currentRunLoop] getCFRunLoop], AXObserverGetRunLoopSource(observer), kCFRunLoopDefaultMode); + + EXPECT(notificationList.length() == 0); + le2->setFocus(); + QCoreApplication::processEvents(); + EXPECT(notificationList.length() == 1); + EXPECT(notificationList.at(0) == QAccessible::Focus); + le1->setFocus(); + QCoreApplication::processEvents(); + EXPECT(notificationList.length() == 2); + EXPECT(notificationList.at(1) == QAccessible::Focus); + le1->setText("hello"); + QCoreApplication::processEvents(); + EXPECT(notificationList.length() == 3); + EXPECT(notificationList.at(2) == QAccessible::ValueChanged); + le1->setText("foo"); + QCoreApplication::processEvents(); + EXPECT(notificationList.length() == 4); + EXPECT(notificationList.at(3) == QAccessible::ValueChanged); + + return true; +} -- cgit v1.2.3 From 1d58ec346ae566a2065aae7acaf3526f28fd6473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simo=20F=C3=A4lt?= Date: Tue, 8 Apr 2014 10:07:15 +0300 Subject: Android: Add some ci usage features to Android testrunner Added new options: - silent to suppress the noice from ext tools, making it easier to parse failed test cases. - ci, to check test insignificance. Requires QMake::Project cpan module if used. Also added printing out results after each test as well as full summary after test run is complete. Task-number: QTQAINFRA-641 Change-Id: Ie5f02710a939f7526e0dd39979a0cd97ed19f55b Reviewed-by: Eskil Abrahamsen Blomfeldt --- tests/auto/android/runtests_androiddeployqt.pl | 176 +++++++++++++++++++++++-- 1 file changed, 167 insertions(+), 9 deletions(-) diff --git a/tests/auto/android/runtests_androiddeployqt.pl b/tests/auto/android/runtests_androiddeployqt.pl index 3d57dcfd65..c949e1cf87 100755 --- a/tests/auto/android/runtests_androiddeployqt.pl +++ b/tests/auto/android/runtests_androiddeployqt.pl @@ -68,9 +68,18 @@ my $android_sdk_dir = "$ENV{'ANDROID_SDK_ROOT'}"; my $android_ndk_dir = "$ENV{'ANDROID_NDK_ROOT'}"; my $android_to_connect = "$ENV{'ANDROID_DEVICE'}"; my $ant_tool = `which ant`; +my $silent = 0; chomp $ant_tool; my $strip_tool=""; my $readelf_tool=""; +# for ci usage +my @failures = ''; +my $total_tests = 0; +my $total_failed = 0; +my $failed_insignificants = 0; +my $ci_use = 0; +my $start = time(); + GetOptions('h|help' => \$help , man => \$man , 's|serial=s' => \$device_serial @@ -87,10 +96,15 @@ GetOptions('h|help' => \$help , 'strip=s' => \$strip_tool , 'readelf=s' => \$readelf_tool , 'testcase=s' => \$testcase + , 'silent' => sub { $silent = 1 } + , 'ci' => sub { $ci_use = 1 } ) or pod2usage(2); pod2usage(1) if $help; pod2usage(-verbose => 2) if $man; +if ($ci_use){ + use QMake::Project; +} my $adb_tool="$android_sdk_dir/platform-tools/adb"; # For CI. Nodes are connecting to test devices over IP, which is stored to env variable @@ -139,6 +153,123 @@ sub popd () dir; } +############################## +# Read possible insignificance +# from pro file +############################## +sub check_if_insignificant +{ + return 0 if ( !$ci_use ); + my $case = shift; + my $insignificant = 0; + my $prj = QMake::Project->new( 'Makefile' ); + $insignificant = $prj->test( 'insignificant_test' ); + return $insignificant; +} + +############################## +# Print output from given +# $testresult.txt file +############################## +sub print_output +{ + my $res_file = shift; + my $case = shift; + my $insignificant = shift; + my $print_all = 0; + $total_tests++; + if (-e $res_file) { + open my $file, $res_file or die "Could not open $res_file: $!"; + while (my $line = <$file>) { + if ($line =~ m/^FAIL/) { + print "$line"; + # Pretend to be like the "real" testrunner and print out + # all steps + $print_all = 1; + } + } + close $file; + if ($print_all) { + # In case we are printing all, the test failed + system("cat $res_file"); + if ($insignificant) { + print " Testrunner: $case failed, but it is marked with insignificant_test\n"; + push (@failures ,(basename($case)." [insignificant]")); + $failed_insignificants++; + } else { + $total_failed++; + push (@failures ,(basename($case))); + } + } else { + my $cmd = "sed -n 'x;\$p' ${res_file}"; + my $summary = qx(${cmd}); + if ($summary =~ m/^Totals/) { + print "$summary"; + } else { + print "Error: The log is incomplete. Looks like you have to increase the timeout."; + # The test log seems inclomplete, considering the test as failed. + if ($insignificant) { + print " Testrunner: $case failed, but it is marked with insignificant_test\n"; + push (@failures ,(basename($case)." [insignificant]")); + $failed_insignificants++; + } else { + $total_failed++; + push (@failures ,(basename($case))); + } + } + } + } else { + if ($insignificant) { + print " Failed to execute $case, but it is marked with insignificant_test\n"; + push (@failures ,(basename($case)." [insignificant]")); + $failed_insignificants++; + } else { + print "Failed to execute $case \n"; + $total_failed++; + push (@failures ,(basename($case))); + } + } +} + +############################## +# Print summary of test run +############################## + +sub print_summary +{ + my $total = time()-$start; + my $h = 0; + my $m = 0; + my $s = 0; + my $exit = 0; + print "=== Timing: =================== TEST RUN COMPLETED! ============================\n"; + if ($total > 60*60) { + $h = int($total/60/60); + $s = int($total - $h*60*60); + + $m = int($s/60); + $s = 0; + print "Total: $h hours $m minutes\n"; + } elsif ($total > 60) { + $m = int($total/60); + $s = int($total - $m*60); + print "Total: $m minutes $s seconds\n"; + } else { + $s = int($total); + print "Total: $s seconds\n"; + } + + print "=== Failures: =================================================================="; + foreach my $failed (@failures) { + print $failed."\n"; + $exit = 1; + } + print "=== Totals: ".$total_tests." tests, ".($total_tests-$total_failed). + " passes, ".$failed_insignificants. + " insignificant fails ======================\n"; + return $exit; +} + sub waitForProcess { @@ -147,8 +278,8 @@ sub waitForProcess my $timeout=shift; my $sleepPeriod=shift; $sleepPeriod=1 if !defined($sleepPeriod); - print "Waiting for $process ".$timeout*$sleepPeriod." seconds to"; - print $action?" start...\n":" die...\n"; + print "Waiting for $process ".$timeout*$sleepPeriod." seconds to" if (!$silent); + print $action?" start...\n":" die...\n" if (!$silent); while ($timeout--) { my $output = `$adb_tool $device_serial shell ps 2>&1`; # get current processes @@ -156,13 +287,13 @@ sub waitForProcess my $res=($output =~ m/.*S $process/)?1:0; # check the procress if ($action == $res) { - print "... succeed\n"; + print "... succeed\n" if (!$silent); return 1; } sleep($sleepPeriod); - print "timeount in ".$timeout*$sleepPeriod." seconds\n" + print "timeount in ".$timeout*$sleepPeriod." seconds\n" if (!$silent); } - print "... failed\n"; + print "... failed\n" if (!$silent); return 0; } @@ -191,6 +322,7 @@ sub startTest my $packageName = "org.qtproject.example.tst_$testName"; my $intentName = "$packageName/org.qtproject.qt5.android.bindings.QtActivity"; my $output_file = shift; + my $insignificance = shift; my $get_xml= 0; my $get_txt= 0; my $testLib =""; @@ -206,7 +338,9 @@ sub startTest $get_txt = 1; } - system("$adb_tool $device_serial shell am start -e applicationArguments \"$testLib\" -n $intentName"); # start intent + my $cmd="${adb_tool} ${device_serial} shell am start -e applicationArguments \"${testLib}\" -n ${intentName}"; + my $res = qx(${cmd}); + print $res if (!$silent); #wait to start (if it has not started and quit already) waitForProcess($packageName,1,10); @@ -223,6 +357,11 @@ sub startTest system("$adb_tool $device_serial pull /data/data/$packageName/output.xml $output_dir/$output_file.xml") if ($get_xml); system("$adb_tool $device_serial pull /data/data/$packageName/output.txt $output_dir/$output_file.txt") if ($get_txt); + if ($get_txt){ + print "Tesresults for $packageName:\n"; + my $insig = + print_output("$output_dir/$output_file.txt", $packageName, $insignificance); + } return 1; } @@ -244,9 +383,18 @@ foreach (split("\n",$testsFiles)) { chomp; #remove white spaces pushd(abs_path(dirname($_))); # cd to application dir - system("make INSTALL_ROOT=$temp_dir install"); # install the application to temp dir + my $insig = check_if_insignificant(); + my $cmd="make INSTALL_ROOT=${temp_dir} install"; + my $res = qx(${cmd}); + print $res if (!$silent); my $application=basename(cwd); - system("androiddeployqt --install $deployqt_device_serial --output $temp_dir --deployment debug --verbose --input android-libtst_$application.so-deployment-settings.json"); + if ($silent) { + $cmd="androiddeployqt --install ${deployqt_device_serial} --output ${temp_dir} --deployment debug --verbose --input android-libtst_${application}.so-deployment-settings.json >/dev/null 2>&1"; + } else { + $cmd="androiddeployqt --install ${deployqt_device_serial} --output ${temp_dir} --deployment debug --verbose --input android-libtst_${application}.so-deployment-settings.json"; + } + $res = qx(${cmd}); + print $res if (!$silent); my $output_name=dirname($_); $output_name =~ s/\.//; # remove first "." character $output_name =~ s/\///; # remove first "/" character @@ -272,12 +420,13 @@ foreach (split("\n",$testsFiles)) } else { - startTest($application, "$output_name") or warn "Can't run $application ...\n"; + startTest($application, "$output_name", $insig) or warn "Can't run $application ...\n"; } popd(); remove_tree( $temp_dir, {keep_root => 1} ); } +print_summary() if ($ci_use); popd(); __END__ @@ -338,6 +487,15 @@ The format of log file, default is xml. The timeout period before stopping individual tests from running. +=item B<-silent> + +Suppress output of system commands. + +=item B<-ci> + +Enables checking if test is insignificant or not. Also prints test +summary after all tests has been executed. + =item B<-h --help> Print a brief help message and exits. -- cgit v1.2.3 From 04f6dffbf9f9b476eed74006de15ad837162e04e Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Tue, 8 Apr 2014 18:16:37 +0200 Subject: QOpenGLWidget: Avoid crashing if updateGL is called before the first resize Change-Id: I9e7788334de98b35dc5d6beee97a63783a1fe267 Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qopenglwidget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index d9bc2f7bbd..10be5aef16 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -147,6 +147,9 @@ void QOpenGLWidget::paintGL() void QOpenGLWidget::updateGL() { Q_D(QOpenGLWidget); + if (d->uninitialized) + return; + makeCurrent(); paintGL(); d->context.functions()->glFlush(); -- cgit v1.2.3 From 82934f11e06f1b1c4084c8fd4bac2e1787f0042a Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 8 Apr 2014 23:38:00 +0200 Subject: Stabilize tst_QListWidget Replace weird QEventLoop hacks by sending all posted deferred delete events. Change-Id: I6da743f2b3fb6ef5dfc960dd3d752973cd511037 Reviewed-by: Friedemann Kleint --- .../widgets/itemviews/qlistwidget/tst_qlistwidget.cpp | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index 153144db63..e02ab0064c 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -209,14 +208,7 @@ void tst_QListWidget::cleanupTestCase() void tst_QListWidget::init() { testWidget->clear(); - - if (testWidget->viewport()->children().count() > 0) { - QEventLoop eventLoop; - for (int i=0; i < testWidget->viewport()->children().count(); ++i) - connect(testWidget->viewport()->children().at(i), SIGNAL(destroyed()), &eventLoop, SLOT(quit())); - QTimer::singleShot(100, &eventLoop, SLOT(quit())); - eventLoop.exec(); - } + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); } void tst_QListWidget::checkDefaultValues() @@ -317,12 +309,7 @@ void tst_QListWidget::closePersistentEditor() // actual test childCount = testWidget->viewport()->children().count(); testWidget->closePersistentEditor(item); - // Spin the event loop and hopefully it will die. - QEventLoop eventLoop; - for (int i=0; i < childCount; ++i) - connect(testWidget->viewport()->children().at(i), SIGNAL(destroyed()), &eventLoop, SLOT(quit())); - QTimer::singleShot(100, &eventLoop, SLOT(quit())); - eventLoop.exec(); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCOMPARE(testWidget->viewport()->children().count(), childCount - 1); } -- cgit v1.2.3 From adde66f0dd7154585af8a77578e39973b5973883 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 7 Apr 2014 10:55:50 +0200 Subject: Update qtgui.qdoc regarding OpenGL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ibda6987d005a1e42ebaef23b41ef18ae0b7ffa66 Reviewed-by: Gunnar Sletta Reviewed-by: Topi Reiniö --- src/gui/doc/src/qtgui.qdoc | 52 +++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc index d22c380145..0e05a617e1 100644 --- a/src/gui/doc/src/qtgui.qdoc +++ b/src/gui/doc/src/qtgui.qdoc @@ -122,22 +122,40 @@ - \section1 OpenGL and OpenGL ES integration - - QWindow supports rendering using desktop OpenGL, OpenGL ES 1.1 and - OpenGL ES 2.0, depending on what the platform supports. OpenGL - rendering is enabled by setting the QWindow's surface type to - QSurface::OpenGLSurface, choosing the format attributes with - QSurfaceFormat, and then creating a QOpenGLContext to manage - the native OpenGL context. In addition, Qt has QOpenGLPaintDevice, - which enables the use of OpenGL accelerated QPainter rendering, as well as - convenience classes that simplify the writing of OpenGL code and hides the - complexities of extension handling and the differences between OpenGL ES 2 - and desktop OpenGL. The convenience classes include QOpenGLFunctions that - lets an application use all the OpenGL ES 2 functions on desktop OpenGL - without having to manually resolve the OpenGL function pointers and some - classes that wrap native OpenGL resources in a simpler Qt API: - QOpenGLBuffer, QOpenGLFramebufferObject, and QOpenGLShaderProgram. + \section1 OpenGL and OpenGL ES Integration + + QWindow supports rendering using OpenGL and OpenGL ES, depending + on what the platform supports. OpenGL rendering is enabled by + setting the QWindow's surface type to QSurface::OpenGLSurface, + choosing the format attributes with QSurfaceFormat, and then + creating a QOpenGLContext to manage the native OpenGL context. In + addition, Qt has QOpenGLPaintDevice, which enables the use of + OpenGL accelerated QPainter rendering, as well as convenience + classes that simplify the writing of OpenGL code and hides the + complexities of extension handling and the differences between + OpenGL ES 2 and desktop OpenGL. The convenience classes include + QOpenGLFunctions that lets an application use all the OpenGL ES 2 + functions on desktop OpenGL without having to manually resolve the + OpenGL function pointers, thus allowing cross-platform development + of applications targeting mobile or embedded devices, and some + classes that wrap native OpenGL functionality in a simpler Qt API: + + \list + \li QOpenGLBuffer + \li QOpenGLFramebufferObject + \li QOpenGLShaderProgram + \li QOpenGLTexture + \li QOpenGLDebugLogger + \li QOpenGLTimerQuery + \li QOpenGLVertexArrayObject + \endlist + + Finally, in order to provide better support for the newer versions + (3.0 and higher) of OpenGL, a versioned function wrapper mechanism + is also available: The QOpenGLFunction_N_N family of classes + expose all the functions in a given OpenGL version and profile, + allowing easy development of desktop applications relying on + modern, desktop-only OpenGL features. For more information, see the \l {OpenGL Window Example}. @@ -147,7 +165,7 @@ A \l {QWindow} created with the \l {QSurface::OpenGLSurface} can be used in combination with \l QPainter and \l QOpenGLPaintDevice - to have OpenGL hardware accellerated 2D graphics, by sacrificing + to have OpenGL hardware accelerated 2D graphics, by sacrificing some of the visual quality. -- cgit v1.2.3 From 0e62671bc0e6df5385b5eb8841b490190e411987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 7 Apr 2014 09:24:37 +0200 Subject: Cocoa: Fix crash when creating printer object. Fix reference counting error in QCocoaPrintDevice:: createPageSize(). "key" is accessed with a "Get" function and should not be released. Switch from using QCFString to a plain CFStringsRef with manual ref counting. Task-number: QTBUG-38023 Change-Id: I04d661bffeb5b3122b0c3c8eaaffdd1af51842fd Reviewed-by: John Layt --- src/plugins/platforms/cocoa/qcocoaprintdevice.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm index 3061e84470..281b140e15 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm @@ -171,15 +171,18 @@ QPrint::DeviceState QCocoaPrintDevice::state() const QPageSize QCocoaPrintDevice::createPageSize(const PMPaper &paper) const { - QCFString key; + CFStringRef key; double width; double height; - QCFString localizedName; + CFStringRef localizedName; if (PMPaperGetPPDPaperName(paper, &key) == noErr && PMPaperGetWidth(paper, &width) == noErr && PMPaperGetHeight(paper, &height) == noErr && PMPaperCreateLocalizedName(paper, m_printer, &localizedName) == noErr) { - return(QPlatformPrintDevice::createPageSize(key, QSize(width, height), localizedName)); + QPageSize pageSize = QPlatformPrintDevice::createPageSize(QString::fromCFString(key),QSize(width, height), + QString::fromCFString(localizedName)); + CFRelease(localizedName); + return pageSize; } return QPageSize(); } -- cgit v1.2.3 From c92fead4333683f7b13fc730203c67834aa478ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 7 Apr 2014 09:26:48 +0200 Subject: Cocoa: Fix possible printing memory leak. The created page format must always be released, even if one of the subsequent PM* functions fails. Change-Id: If42aaeccd6bdb51ba53444f491ca2878783d0678 Reviewed-by: John Layt --- src/plugins/platforms/cocoa/qcocoaprintdevice.mm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm index 281b140e15..57d5c800e0 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm @@ -219,10 +219,11 @@ QPageSize QCocoaPrintDevice::defaultPageSize() const QPageSize pageSize; PMPageFormat pageFormat; PMPaper paper; - if (PMCreatePageFormat(&pageFormat) == noErr - && PMSessionDefaultPageFormat(m_session, pageFormat) == noErr - && PMGetPageFormatPaper(pageFormat, &paper) == noErr) { - pageSize = createPageSize(paper); + if (PMCreatePageFormat(&pageFormat) == noErr) { + if (PMSessionDefaultPageFormat(m_session, pageFormat) == noErr + && PMGetPageFormatPaper(pageFormat, &paper) == noErr) { + pageSize = createPageSize(paper); + } PMRelease(pageFormat); } return pageSize; -- cgit v1.2.3 From 323ce42de637fa2b5e456dda27d07bcb0c715456 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Apr 2014 00:09:43 +0200 Subject: QPageSize: remove QPageSize:: overqualifications This is not Qt style, not needed, and clutters the code, so remove QPageSize:: qualifications where they're not needed. Change-Id: Ia93ac9523ef43a40cf4dab3bcb383a54af666c96 Reviewed-by: Friedemann Kleint --- src/gui/painting/qpagesize.cpp | 292 ++++++++++++++++++++--------------------- src/gui/painting/qpagesize.h | 42 +++--- 2 files changed, 167 insertions(+), 167 deletions(-) diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp index 445c78e530..978aef905a 100644 --- a/src/gui/painting/qpagesize.cpp +++ b/src/gui/painting/qpagesize.cpp @@ -1131,7 +1131,7 @@ QPageSize::QPageSize() be valid. Use the custom size constructor instead. */ -QPageSize::QPageSize(QPageSize::PageSizeId pageSize) +QPageSize::QPageSize(PageSizeId pageSize) : d(new QPageSizePrivate(pageSize)) { } @@ -1174,7 +1174,7 @@ QPageSize::QPageSize(const QSize &pointSize, const QString &name, SizeMatchPolic "Custom (width x height)" where the size is expressed in units provided. */ -QPageSize::QPageSize(const QSizeF &size, QPageSize::Unit units, +QPageSize::QPageSize(const QSizeF &size, Unit units, const QString &name, SizeMatchPolicy matchPolicy) : d(new QPageSizePrivate(size, units, name, matchPolicy)) { @@ -1343,7 +1343,7 @@ QString QPageSize::name() const QPageSize::PageSizeId QPageSize::id() const { - return isValid() ? d->m_id : QPageSize::Custom; + return isValid() ? d->m_id : Custom; } /*! @@ -1361,7 +1361,7 @@ int QPageSize::windowsId() const { if (!isValid()) return 0; - return d->m_windowsId > 0 ? d->m_windowsId : QPageSize::windowsId(d->m_id); + return d->m_windowsId > 0 ? d->m_windowsId : windowsId(d->m_id); } /*! @@ -1401,7 +1401,7 @@ QSizeF QPageSize::definitionSize() const QPageSize::Unit QPageSize::definitionUnits() const { - return isValid() ? d->m_units : QPageSize::Unit(-1); + return isValid() ? d->m_units : Unit(-1); } /*! @@ -1410,7 +1410,7 @@ QPageSize::Unit QPageSize::definitionUnits() const If the QPageSize is invalid then the QSizeF will be invalid. */ -QSizeF QPageSize::size(QPageSize::Unit units) const +QSizeF QPageSize::size(Unit units) const { return isValid() ? d->size(units) : QSize(); } @@ -1443,7 +1443,7 @@ QSize QPageSize::sizePixels(int resolution) const If the QPageSize is invalid then the QRect will be invalid. */ -QRectF QPageSize::rect(QPageSize::Unit units) const +QRectF QPageSize::rect(Unit units) const { return isValid() ? QRectF(QPointF(0, 0), d->size(units)) : QRectF(); } @@ -1478,9 +1478,9 @@ QRect QPageSize::rectPixels(int resolution) const If the QPageSize is invalid then the key will be empty. */ -QString QPageSize::key(QPageSize::PageSizeId pageSizeId) +QString QPageSize::key(PageSizeId pageSizeId) { - if (pageSizeId < QPageSize::PageSizeId(0) || pageSizeId > QPageSize::LastPageSize) + if (pageSizeId < PageSizeId(0) || pageSizeId > LastPageSize) return QString(); return QString::fromUtf8(qt_pageSizes[pageSizeId].mediaOption); } @@ -1497,249 +1497,249 @@ static QString msgImperialPageSizeInch(int width, int height) If the QPageSize is invalid then the name will be empty. */ -QString QPageSize::name(QPageSize::PageSizeId pageSizeId) +QString QPageSize::name(PageSizeId pageSizeId) { - if (pageSizeId < QPageSize::PageSizeId(0) || pageSizeId > QPageSize::LastPageSize) + if (pageSizeId < PageSizeId(0) || pageSizeId > LastPageSize) return QString(); switch (pageSizeId) { - case QPageSize::A0: + case A0: return QCoreApplication::translate("QPageSize", "A0"); - case QPageSize::A1: + case A1: return QCoreApplication::translate("QPageSize", "A1"); - case QPageSize::A2: + case A2: return QCoreApplication::translate("QPageSize", "A2"); - case QPageSize::A3: + case A3: return QCoreApplication::translate("QPageSize", "A3"); - case QPageSize::A4: + case A4: return QCoreApplication::translate("QPageSize", "A4"); - case QPageSize::A5: + case A5: return QCoreApplication::translate("QPageSize", "A5"); - case QPageSize::A6: + case A6: return QCoreApplication::translate("QPageSize", "A6"); - case QPageSize::A7: + case A7: return QCoreApplication::translate("QPageSize", "A7"); - case QPageSize::A8: + case A8: return QCoreApplication::translate("QPageSize", "A8"); - case QPageSize::A9: + case A9: return QCoreApplication::translate("QPageSize", "A9"); - case QPageSize::A10: + case A10: return QCoreApplication::translate("QPageSize", "A10"); - case QPageSize::B0: + case B0: return QCoreApplication::translate("QPageSize", "B0"); - case QPageSize::B1: + case B1: return QCoreApplication::translate("QPageSize", "B1"); - case QPageSize::B2: + case B2: return QCoreApplication::translate("QPageSize", "B2"); - case QPageSize::B3: + case B3: return QCoreApplication::translate("QPageSize", "B3"); - case QPageSize::B4: + case B4: return QCoreApplication::translate("QPageSize", "B4"); - case QPageSize::B5: + case B5: return QCoreApplication::translate("QPageSize", "B5"); - case QPageSize::B6: + case B6: return QCoreApplication::translate("QPageSize", "B6"); - case QPageSize::B7: + case B7: return QCoreApplication::translate("QPageSize", "B7"); - case QPageSize::B8: + case B8: return QCoreApplication::translate("QPageSize", "B8"); - case QPageSize::B9: + case B9: return QCoreApplication::translate("QPageSize", "B9"); - case QPageSize::B10: + case B10: return QCoreApplication::translate("QPageSize", "B10"); - case QPageSize::Executive: + case Executive: return QCoreApplication::translate("QPageSize", "Executive (7.5 x 10 in)"); - case QPageSize::ExecutiveStandard: + case ExecutiveStandard: return QCoreApplication::translate("QPageSize", "Executive (7.25 x 10.5 in)"); - case QPageSize::Folio: + case Folio: return QCoreApplication::translate("QPageSize", "Folio (8.27 x 13 in)"); - case QPageSize::Legal: + case Legal: return QCoreApplication::translate("QPageSize", "Legal"); - case QPageSize::Letter: + case Letter: return QCoreApplication::translate("QPageSize", "Letter / ANSI A"); - case QPageSize::Tabloid: + case Tabloid: return QCoreApplication::translate("QPageSize", "Tabloid / ANSI B"); - case QPageSize::Ledger: + case Ledger: return QCoreApplication::translate("QPageSize", "Ledger / ANSI B"); - case QPageSize::Custom: + case Custom: return QCoreApplication::translate("QPageSize", "Custom"); - case QPageSize::A3Extra: + case A3Extra: return QCoreApplication::translate("QPageSize", "A3 Extra"); - case QPageSize::A4Extra: + case A4Extra: return QCoreApplication::translate("QPageSize", "A4 Extra"); - case QPageSize::A4Plus: + case A4Plus: return QCoreApplication::translate("QPageSize", "A4 Plus"); - case QPageSize::A4Small: + case A4Small: return QCoreApplication::translate("QPageSize", "A4 Small"); - case QPageSize::A5Extra: + case A5Extra: return QCoreApplication::translate("QPageSize", "A5 Extra"); - case QPageSize::B5Extra: + case B5Extra: return QCoreApplication::translate("QPageSize", "B5 Extra"); - case QPageSize::JisB0: + case JisB0: return QCoreApplication::translate("QPageSize", "JIS B0"); - case QPageSize::JisB1: + case JisB1: return QCoreApplication::translate("QPageSize", "JIS B1"); - case QPageSize::JisB2: + case JisB2: return QCoreApplication::translate("QPageSize", "JIS B2"); - case QPageSize::JisB3: + case JisB3: return QCoreApplication::translate("QPageSize", "JIS B3"); - case QPageSize::JisB4: + case JisB4: return QCoreApplication::translate("QPageSize", "JIS B4"); - case QPageSize::JisB5: + case JisB5: return QCoreApplication::translate("QPageSize", "JIS B5"); - case QPageSize::JisB6: + case JisB6: return QCoreApplication::translate("QPageSize", "JIS B6"); - case QPageSize::JisB7: + case JisB7: return QCoreApplication::translate("QPageSize", "JIS B7"); - case QPageSize::JisB8: + case JisB8: return QCoreApplication::translate("QPageSize", "JIS B8"); - case QPageSize::JisB9: + case JisB9: return QCoreApplication::translate("QPageSize", "JIS B9"); - case QPageSize::JisB10: + case JisB10: return QCoreApplication::translate("QPageSize", "JIS B10"); - case QPageSize::AnsiC: + case AnsiC: return QCoreApplication::translate("QPageSize", "ANSI C"); - case QPageSize::AnsiD: + case AnsiD: return QCoreApplication::translate("QPageSize", "ANSI D"); - case QPageSize::AnsiE: + case AnsiE: return QCoreApplication::translate("QPageSize", "ANSI E"); - case QPageSize::LegalExtra: + case LegalExtra: return QCoreApplication::translate("QPageSize", "Legal Extra"); - case QPageSize::LetterExtra: + case LetterExtra: return QCoreApplication::translate("QPageSize", "Letter Extra"); - case QPageSize::LetterPlus: + case LetterPlus: return QCoreApplication::translate("QPageSize", "Letter Plus"); - case QPageSize::LetterSmall: + case LetterSmall: return QCoreApplication::translate("QPageSize", "Letter Small"); - case QPageSize::TabloidExtra: + case TabloidExtra: return QCoreApplication::translate("QPageSize", "Tabloid Extra"); - case QPageSize::ArchA: + case ArchA: return QCoreApplication::translate("QPageSize", "Architect A"); - case QPageSize::ArchB: + case ArchB: return QCoreApplication::translate("QPageSize", "Architect B"); - case QPageSize::ArchC: + case ArchC: return QCoreApplication::translate("QPageSize", "Architect C"); - case QPageSize::ArchD: + case ArchD: return QCoreApplication::translate("QPageSize", "Architect D"); - case QPageSize::ArchE: + case ArchE: return QCoreApplication::translate("QPageSize", "Architect E"); - case QPageSize::Imperial7x9: + case Imperial7x9: return msgImperialPageSizeInch(7, 9); - case QPageSize::Imperial8x10: + case Imperial8x10: return msgImperialPageSizeInch(8, 10); - case QPageSize::Imperial9x11: + case Imperial9x11: return msgImperialPageSizeInch(9, 11); - case QPageSize::Imperial9x12: + case Imperial9x12: return msgImperialPageSizeInch(9, 12); - case QPageSize::Imperial10x11: + case Imperial10x11: return msgImperialPageSizeInch(10, 11); - case QPageSize::Imperial10x13: + case Imperial10x13: return msgImperialPageSizeInch(10, 13); - case QPageSize::Imperial10x14: + case Imperial10x14: return msgImperialPageSizeInch(10, 14); - case QPageSize::Imperial12x11: + case Imperial12x11: return msgImperialPageSizeInch(12, 11); - case QPageSize::Imperial15x11: + case Imperial15x11: return msgImperialPageSizeInch(15, 11); - case QPageSize::Note: + case Note: return QCoreApplication::translate("QPageSize", "Note"); - case QPageSize::Quarto: + case Quarto: return QCoreApplication::translate("QPageSize", "Quarto"); - case QPageSize::Statement: + case Statement: return QCoreApplication::translate("QPageSize", "Statement"); - case QPageSize::SuperA: + case SuperA: return QCoreApplication::translate("QPageSize", "Super A"); - case QPageSize::SuperB: + case SuperB: return QCoreApplication::translate("QPageSize", "Super B"); - case QPageSize::Postcard: + case Postcard: return QCoreApplication::translate("QPageSize", "Postcard"); - case QPageSize::DoublePostcard: + case DoublePostcard: return QCoreApplication::translate("QPageSize", "Double Postcard"); - case QPageSize::Prc16K: + case Prc16K: return QCoreApplication::translate("QPageSize", "PRC 16K"); - case QPageSize::Prc32K: + case Prc32K: return QCoreApplication::translate("QPageSize", "PRC 32K"); - case QPageSize::Prc32KBig: + case Prc32KBig: return QCoreApplication::translate("QPageSize", "PRC 32K Big"); - case QPageSize::FanFoldUS: + case FanFoldUS: return QCoreApplication::translate("QPageSize", "Fan-fold US (14.875 x 11 in)"); - case QPageSize::FanFoldGerman: + case FanFoldGerman: return QCoreApplication::translate("QPageSize", "Fan-fold German (8.5 x 12 in)"); - case QPageSize::FanFoldGermanLegal: + case FanFoldGermanLegal: return QCoreApplication::translate("QPageSize", "Fan-fold German Legal (8.5 x 13 in)"); - case QPageSize::EnvelopeB4: + case EnvelopeB4: return QCoreApplication::translate("QPageSize", "Envelope B4"); - case QPageSize::EnvelopeB5: + case EnvelopeB5: return QCoreApplication::translate("QPageSize", "Envelope B5"); - case QPageSize::EnvelopeB6: + case EnvelopeB6: return QCoreApplication::translate("QPageSize", "Envelope B6"); - case QPageSize::EnvelopeC0: + case EnvelopeC0: return QCoreApplication::translate("QPageSize", "Envelope C0"); - case QPageSize::EnvelopeC1: + case EnvelopeC1: return QCoreApplication::translate("QPageSize", "Envelope C1"); - case QPageSize::EnvelopeC2: + case EnvelopeC2: return QCoreApplication::translate("QPageSize", "Envelope C2"); - case QPageSize::EnvelopeC3: + case EnvelopeC3: return QCoreApplication::translate("QPageSize", "Envelope C3"); - case QPageSize::EnvelopeC4: + case EnvelopeC4: return QCoreApplication::translate("QPageSize", "Envelope C4"); - case QPageSize::EnvelopeC5: // C5E + case EnvelopeC5: // C5E return QCoreApplication::translate("QPageSize", "Envelope C5"); - case QPageSize::EnvelopeC6: + case EnvelopeC6: return QCoreApplication::translate("QPageSize", "Envelope C6"); - case QPageSize::EnvelopeC65: + case EnvelopeC65: return QCoreApplication::translate("QPageSize", "Envelope C65"); - case QPageSize::EnvelopeC7: + case EnvelopeC7: return QCoreApplication::translate("QPageSize", "Envelope C7"); - case QPageSize::EnvelopeDL: // DLE: + case EnvelopeDL: // DLE: return QCoreApplication::translate("QPageSize", "Envelope DL"); - case QPageSize::Envelope9: + case Envelope9: return QCoreApplication::translate("QPageSize", "Envelope US 9"); - case QPageSize::Envelope10: // Comm10E + case Envelope10: // Comm10E return QCoreApplication::translate("QPageSize", "Envelope US 10"); - case QPageSize::Envelope11: + case Envelope11: return QCoreApplication::translate("QPageSize", "Envelope US 11"); - case QPageSize::Envelope12: + case Envelope12: return QCoreApplication::translate("QPageSize", "Envelope US 12"); - case QPageSize::Envelope14: + case Envelope14: return QCoreApplication::translate("QPageSize", "Envelope US 14"); - case QPageSize::EnvelopeMonarch: + case EnvelopeMonarch: return QCoreApplication::translate("QPageSize", "Envelope Monarch"); - case QPageSize::EnvelopePersonal: + case EnvelopePersonal: return QCoreApplication::translate("QPageSize", "Envelope Personal"); - case QPageSize::EnvelopeChou3: + case EnvelopeChou3: return QCoreApplication::translate("QPageSize", "Envelope Chou 3"); - case QPageSize::EnvelopeChou4: + case EnvelopeChou4: return QCoreApplication::translate("QPageSize", "Envelope Chou 4"); - case QPageSize::EnvelopeInvite: + case EnvelopeInvite: return QCoreApplication::translate("QPageSize", "Envelope Invite"); - case QPageSize::EnvelopeItalian: + case EnvelopeItalian: return QCoreApplication::translate("QPageSize", "Envelope Italian"); - case QPageSize::EnvelopeKaku2: + case EnvelopeKaku2: return QCoreApplication::translate("QPageSize", "Envelope Kaku 2"); - case QPageSize::EnvelopeKaku3: + case EnvelopeKaku3: return QCoreApplication::translate("QPageSize", "Envelope Kaku 3"); - case QPageSize::EnvelopePrc1: + case EnvelopePrc1: return QCoreApplication::translate("QPageSize", "Envelope PRC 1"); - case QPageSize::EnvelopePrc2: + case EnvelopePrc2: return QCoreApplication::translate("QPageSize", "Envelope PRC 2"); - case QPageSize::EnvelopePrc3: + case EnvelopePrc3: return QCoreApplication::translate("QPageSize", "Envelope PRC 3"); - case QPageSize::EnvelopePrc4: + case EnvelopePrc4: return QCoreApplication::translate("QPageSize", "Envelope PRC 4"); - case QPageSize::EnvelopePrc5: + case EnvelopePrc5: return QCoreApplication::translate("QPageSize", "Envelope PRC 5"); - case QPageSize::EnvelopePrc6: + case EnvelopePrc6: return QCoreApplication::translate("QPageSize", "Envelope PRC 6"); - case QPageSize::EnvelopePrc7: + case EnvelopePrc7: return QCoreApplication::translate("QPageSize", "Envelope PRC 7"); - case QPageSize::EnvelopePrc8: + case EnvelopePrc8: return QCoreApplication::translate("QPageSize", "Envelope PRC 8"); - case QPageSize::EnvelopePrc9: + case EnvelopePrc9: return QCoreApplication::translate("QPageSize", "Envelope PRC 9"); - case QPageSize::EnvelopePrc10: + case EnvelopePrc10: return QCoreApplication::translate("QPageSize", "Envelope PRC 10"); - case QPageSize::EnvelopeYou4: + case EnvelopeYou4: return QCoreApplication::translate("QPageSize", "Envelope You 4"); } return QString(); @@ -1755,7 +1755,7 @@ QString QPageSize::name(QPageSize::PageSizeId pageSizeId) point size of the PageSizeId before using it in any calculations. */ -QPageSize::PageSizeId QPageSize::id(const QSize &pointSize, QPageSize::SizeMatchPolicy matchPolicy) +QPageSize::PageSizeId QPageSize::id(const QSize &pointSize, SizeMatchPolicy matchPolicy) { return qt_idForPointSize(pointSize, matchPolicy, 0); } @@ -1770,8 +1770,8 @@ QPageSize::PageSizeId QPageSize::id(const QSize &pointSize, QPageSize::SizeMatch unit size of the PageSizeId before using it in any calculations. */ -QPageSize::PageSizeId QPageSize::id(const QSizeF &size, QPageSize::Unit units, - QPageSize::SizeMatchPolicy matchPolicy) +QPageSize::PageSizeId QPageSize::id(const QSizeF &size, Unit units, + SizeMatchPolicy matchPolicy) { return qt_idForSize(size, units, matchPolicy, 0); } @@ -1794,7 +1794,7 @@ QPageSize::PageSizeId QPageSize::id(int windowsId) will be returned. */ -int QPageSize::windowsId(QPageSize::PageSizeId pageSizeId) +int QPageSize::windowsId(PageSizeId pageSizeId) { return qt_pageSizes[pageSizeId].windowsId; } @@ -1805,9 +1805,9 @@ int QPageSize::windowsId(QPageSize::PageSizeId pageSizeId) To obtain the definition units, call QPageSize::definitionUnits(). */ -QSizeF QPageSize::definitionSize(QPageSize::PageSizeId pageSizeId) +QSizeF QPageSize::definitionSize(PageSizeId pageSizeId) { - if (pageSizeId == QPageSize::Custom) + if (pageSizeId == Custom) return QSizeF(); return qt_definitionSize(pageSizeId); } @@ -1818,10 +1818,10 @@ QSizeF QPageSize::definitionSize(QPageSize::PageSizeId pageSizeId) To obtain the definition size, call QPageSize::definitionSize(). */ -QPageSize::Unit QPageSize::definitionUnits(QPageSize::PageSizeId pageSizeId) +QPageSize::Unit QPageSize::definitionUnits(PageSizeId pageSizeId) { - if (pageSizeId == QPageSize::Custom) - return QPageSize::Unit(-1); + if (pageSizeId == Custom) + return Unit(-1); return qt_pageSizes[pageSizeId].definitionUnits; } @@ -1829,9 +1829,9 @@ QPageSize::Unit QPageSize::definitionUnits(QPageSize::PageSizeId pageSizeId) Returns the size of the standard \a pageSizeId in the requested \a units. */ -QSizeF QPageSize::size(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units) +QSizeF QPageSize::size(PageSizeId pageSizeId, Unit units) { - if (pageSizeId == QPageSize::Custom) + if (pageSizeId == Custom) return QSizeF(); return qt_unitSize(pageSizeId, units); } @@ -1840,9 +1840,9 @@ QSizeF QPageSize::size(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units) Returns the size of the standard \a pageSizeId in Points. */ -QSize QPageSize::sizePoints(QPageSize::PageSizeId pageSizeId) +QSize QPageSize::sizePoints(PageSizeId pageSizeId) { - if (pageSizeId == QPageSize::Custom) + if (pageSizeId == Custom) return QSize(); return QSize(qt_pageSizes[pageSizeId].widthPoints, qt_pageSizes[pageSizeId].heightPoints); } @@ -1852,11 +1852,11 @@ QSize QPageSize::sizePoints(QPageSize::PageSizeId pageSizeId) for the given \a resolution. */ -QSize QPageSize::sizePixels(QPageSize::PageSizeId pageSizeId, int resolution) +QSize QPageSize::sizePixels(PageSizeId pageSizeId, int resolution) { - if (pageSizeId == QPageSize::Custom) + if (pageSizeId == Custom) return QSize(); - return qt_convertPointsToPixels(QPageSize::sizePoints(pageSizeId), resolution); + return qt_convertPointsToPixels(sizePoints(pageSizeId), resolution); } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/painting/qpagesize.h b/src/gui/painting/qpagesize.h index 8205d2eae4..ae337a2438 100644 --- a/src/gui/painting/qpagesize.h +++ b/src/gui/painting/qpagesize.h @@ -229,13 +229,13 @@ public: }; QPageSize(); - explicit QPageSize(QPageSize::PageSizeId pageSizeId); + explicit QPageSize(PageSizeId pageSizeId); explicit QPageSize(const QSize &pointSize, const QString &name = QString(), - QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch); - explicit QPageSize(const QSizeF &size, QPageSize::Unit units, + SizeMatchPolicy matchPolicy = FuzzyMatch); + explicit QPageSize(const QSizeF &size, Unit units, const QString &name = QString(), - QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch); + SizeMatchPolicy matchPolicy = FuzzyMatch); QPageSize(const QPageSize &other); ~QPageSize(); @@ -254,38 +254,38 @@ public: QString key() const; QString name() const; - QPageSize::PageSizeId id() const; + PageSizeId id() const; int windowsId() const; QSizeF definitionSize() const; - QPageSize::Unit definitionUnits() const; + Unit definitionUnits() const; - QSizeF size(QPageSize::Unit units) const; + QSizeF size(Unit units) const; QSize sizePoints() const; QSize sizePixels(int resolution) const; - QRectF rect(QPageSize::Unit units) const; + QRectF rect(Unit units) const; QRect rectPoints() const; QRect rectPixels(int resolution) const; - static QString key(QPageSize::PageSizeId pageSizeId); - static QString name(QPageSize::PageSizeId pageSizeId); + static QString key(PageSizeId pageSizeId); + static QString name(PageSizeId pageSizeId); - static QPageSize::PageSizeId id(const QSize &pointSize, - QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch); - static QPageSize::PageSizeId id(const QSizeF &size, QPageSize::Unit units, - QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch); + static PageSizeId id(const QSize &pointSize, + SizeMatchPolicy matchPolicy = FuzzyMatch); + static PageSizeId id(const QSizeF &size, Unit units, + SizeMatchPolicy matchPolicy = FuzzyMatch); - static QPageSize::PageSizeId id(int windowsId); - static int windowsId(QPageSize::PageSizeId pageSizeId); + static PageSizeId id(int windowsId); + static int windowsId(PageSizeId pageSizeId); - static QSizeF definitionSize(QPageSize::PageSizeId pageSizeId); - static QPageSize::Unit definitionUnits(QPageSize::PageSizeId pageSizeId); + static QSizeF definitionSize(PageSizeId pageSizeId); + static Unit definitionUnits(PageSizeId pageSizeId); - static QSizeF size(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units); - static QSize sizePoints(QPageSize::PageSizeId pageSizeId); - static QSize sizePixels(QPageSize::PageSizeId pageSizeId, int resolution); + static QSizeF size(PageSizeId pageSizeId, Unit units); + static QSize sizePoints(PageSizeId pageSizeId); + static QSize sizePixels(PageSizeId pageSizeId, int resolution); private: friend class QPageSizePrivate; -- cgit v1.2.3 From 624df9cf7fcf844ae1af0e7c8e465adb164bedd0 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 13 Jan 2014 14:35:17 +0100 Subject: Cocoa: Use private property to enable NSWindow child windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enabled for QToolBar to allow it to overlap OpenGL widgets when expanding. Task-number: QTBUG-33082 Change-Id: I76dc8da52bc04eedc6d6779c48753da100ed1c9f Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 9 ++++++++- src/widgets/widgets/qtoolbar.cpp | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 666e18715f..b07b5e33be 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1215,11 +1215,18 @@ QCocoaGLContext *QCocoaWindow::currentContext() const void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) { bool wasNSWindowChild = m_isNSWindowChild; - // TODO Set value for m_isNSWindowChild here + m_isNSWindowChild = parentWindow && (window()->property("_q_platform_MacUseNSWindow").toBool()); bool needsNSWindow = m_isNSWindowChild || !parentWindow; QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow; m_parentCocoaWindow = const_cast(static_cast(parentWindow)); + if (m_parentCocoaWindow && m_isNSWindowChild) { + QWindow *parentQWindow = m_parentCocoaWindow->window(); + if (!parentQWindow->property("_q_platform_MacUseNSWindow").toBool()) { + parentQWindow->setProperty("_q_platform_MacUseNSWindow", QVariant(true)); + m_parentCocoaWindow->recreateWindow(m_parentCocoaWindow->m_parentCocoaWindow); + } + } bool usesNSPanel = [m_nsWindow isKindOfClass:[QNSPanel class]]; diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index d20b7a380d..53b77c34da 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -83,6 +83,7 @@ void QToolBarPrivate::init() q->setBackgroundRole(QPalette::Button); q->setAttribute(Qt::WA_Hover); q->setAttribute(Qt::WA_X11NetWmWindowTypeToolBar); + q->setProperty("_q_platform_MacUseNSWindow", QVariant(true)); QStyle *style = q->style(); int e = style->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q); -- cgit v1.2.3 From 9ee07d5544f0194cb7dd58e4383d25a08226acde Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 3 Apr 2014 17:50:42 +0200 Subject: QComboBox: Set the proper font after a MacSizeChange event Change-Id: I5c90817e52a3e87d9b06b2bb670d69a6953efd47 Reviewed-by: Jens Bache-Wiig --- src/widgets/widgets/qcombobox.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 1ba08bd25f..06258cb4a6 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2834,6 +2834,18 @@ void QComboBox::changeEvent(QEvent *e) d->updateLineEditGeometry(); d->setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem); + if (e->type() == QEvent::MacSizeChange){ + QPlatformTheme::Font f = QPlatformTheme::SystemFont; + if (testAttribute(Qt::WA_MacSmallSize)) + f = QPlatformTheme::SmallFont; + else if (testAttribute(Qt::WA_MacMiniSize)) + f = QPlatformTheme::MiniFont; + if (const QFont *platformFont = QApplicationPrivate::platformTheme()->font(f)) { + QFont f = font(); + f.setPointSizeF(platformFont->pointSizeF()); + setFont(f); + } + } // ### need to update scrollers etc. as well here break; case QEvent::EnabledChange: -- cgit v1.2.3 From 670ebed1214ed0dae9a52ab40c5b5065c7d02a35 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 4 Apr 2014 11:51:16 +0200 Subject: Fix out-of-range shifting offsetHi needs to be casted first before shifting. Change-Id: I29c773dd13d5b16042629604015bbf5645fab861 Reviewed-by: Andrew Knight --- src/corelib/io/qfsfileengine_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index afc8deb1a0..fb4107b95d 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1034,8 +1034,8 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, LPVOID mapAddress = ::MapViewOfFile(mapHandle, access, offsetHi, offsetLo, size + extra); #else - offset = (offsetHi << 32) + offsetLo; - LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, offset, size); + LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, + (ULONG64(offsetHi) << 32) + offsetLo, size); #endif if (mapAddress) { uchar *address = extra + static_cast(mapAddress); -- cgit v1.2.3 From db14f5fd605904965402042d656c73fc65fb6615 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 7 Apr 2014 10:38:26 +0200 Subject: Android: Fix compilation on Windows 151cf2047aa36ac395a841a3ced8b2142a997aec broke cross-compilation for Android on Windows, since evdev-support was detected, but there was no corresponding test to disable the mtdev-code in the evdev files. Task-number: QTBUG-38155 Change-Id: Ifb08fa1160a348ef64b970a89922e66dc6ddd263 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 76072121aa..d149511218 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -191,6 +191,7 @@ Configure::Configure(int& argc, char** argv) dictionary[ "QT_GLIB" ] = "no"; dictionary[ "QT_ICONV" ] = "auto"; dictionary[ "QT_EVDEV" ] = "auto"; + dictionary[ "QT_MTDEV" ] = "auto"; dictionary[ "QT_INOTIFY" ] = "auto"; dictionary[ "QT_EVENTFD" ] = "auto"; dictionary[ "QT_CUPS" ] = "auto"; @@ -1268,6 +1269,12 @@ void Configure::parseCmdLine() dictionary[ "QT_EVDEV" ] = "yes"; } + else if (configCmdLine.at(i) == "-no-mtdev") { + dictionary[ "QT_MTDEV" ] = "no"; + } else if (configCmdLine.at(i) == "-mtdev") { + dictionary[ "QT_MTDEV" ] = "yes"; + } + else if (configCmdLine.at(i) == "-inotify") { dictionary["QT_INOTIFY"] = "yes"; } else if (configCmdLine.at(i) == "-no-inotify") { @@ -1682,6 +1689,7 @@ void Configure::applySpecSpecifics() dictionary[ "QT_GLIB" ] = "no"; dictionary[ "QT_ICONV" ] = "no"; dictionary[ "QT_EVDEV" ] = "no"; + dictionary[ "QT_MTDEV" ] = "no"; dictionary[ "FONT_CONFIG" ] = "auto"; dictionary["DECORATIONS"] = "default windows styled"; @@ -1846,6 +1854,9 @@ bool Configure::displayHelp() desc("QT_EVDEV", "no", "-no-evdev", "Do not enable support for evdev."); desc("QT_EVDEV", "yes", "-evdev", "Enable support for evdev."); + desc("QT_MTDEV", "no", "-no-mtdev", "Do not enable support for mtdev."); + desc("QT_MTDEV", "yes", "-mtdev", "Enable support for mtdev."); + desc("QT_INOTIFY", "yes", "-inotify", "Explicitly enable Qt inotify(7) support."); desc("QT_INOTIFY", "no", "-no-inotify", "Explicitly disable Qt inotify(7) support.\n"); @@ -2257,6 +2268,8 @@ bool Configure::checkAvailability(const QString &part) available = tryCompileProject("unix/iconv") || tryCompileProject("unix/gnu-libiconv"); } else if (part == "EVDEV") { available = tryCompileProject("unix/evdev"); + } else if (part == "MTDEV") { + available = tryCompileProject("unix/mtdev"); } else if (part == "INOTIFY") { available = tryCompileProject("unix/inotify"); } else if (part == "QT_EVENTFD") { @@ -2411,6 +2424,10 @@ void Configure::autoDetection() if (dictionary["QT_EVDEV"] == "auto") dictionary["QT_EVDEV"] = checkAvailability("EVDEV") ? "yes" : "no"; + // Detection of mtdev support + if (dictionary["QT_MTDEV"] == "auto") + dictionary["QT_MTDEV"] = checkAvailability("MTDEV") ? "yes" : "no"; + // Detection of inotify if (dictionary["QT_INOTIFY"] == "auto") dictionary["QT_INOTIFY"] = checkAvailability("INOTIFY") ? "yes" : "no"; @@ -2833,6 +2850,9 @@ void Configure::generateOutputVars() if (dictionary["QT_EVDEV"] == "yes") qtConfig += "evdev"; + if (dictionary["QT_MTDEV"] == "yes") + qtConfig += "mtdev"; + if (dictionary["QT_INOTIFY"] == "yes") qtConfig += "inotify"; @@ -3513,6 +3533,7 @@ void Configure::generateConfigfiles() if (dictionary["QT_CUPS"] == "no") qconfigList += "QT_NO_CUPS"; if (dictionary["QT_ICONV"] == "no") qconfigList += "QT_NO_ICONV"; if (dictionary["QT_EVDEV"] == "no") qconfigList += "QT_NO_EVDEV"; + if (dictionary["QT_MTDEV"] == "no") qconfigList += "QT_NO_MTDEV"; if (dictionary["QT_GLIB"] == "no") qconfigList += "QT_NO_GLIB"; if (dictionary["QT_INOTIFY"] == "no") qconfigList += "QT_NO_INOTIFY"; if (dictionary["QT_EVENTFD"] == "no") qconfigList += "QT_NO_EVENTFD"; @@ -3612,6 +3633,7 @@ void Configure::displayConfig() sout << "NIS support................." << dictionary[ "NIS" ] << endl; sout << "Iconv support..............." << dictionary[ "QT_ICONV" ] << endl; sout << "Evdev support..............." << dictionary[ "QT_EVDEV" ] << endl; + sout << "Mtdev support..............." << dictionary[ "QT_MTDEV" ] << endl; sout << "Inotify support............." << dictionary[ "QT_INOTIFY" ] << endl; sout << "eventfd(7) support.........." << dictionary[ "QT_EVENTFD" ] << endl; sout << "Glib support................" << dictionary[ "QT_GLIB" ] << endl; -- cgit v1.2.3 From 4af257eb3cfeef93adefda5f981742ffb58ba0ad Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 8 Apr 2014 09:38:28 +0200 Subject: QNX: Work around dlclose issue "Shared objects still referenced" dlerror should actually be treated as "for your information" only, not as an actual error. Change-Id: Ie02bd1db0dd2dc93bb759f8b6c7e825070e17bb9 Reviewed-by: Fabian Bumberger --- src/corelib/plugin/qlibrary_unix.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index e89d6396f6..43e2b5c15b 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -273,7 +273,15 @@ bool QLibraryPrivate::unload_sys() # else if (dlclose(pHnd)) { # endif +# if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in + char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance + if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative" + return true; + errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName) + .arg(QLatin1String(error)); +# else errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName).arg(qdlerror()); +# endif return false; } #endif -- cgit v1.2.3 From b490116f82901b26c1eb6d071ba5ea269afef657 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 2 Apr 2014 23:21:24 +0200 Subject: QNX: Fix QHeaderView autotest Some margines and sizeHints are DPI dependent on QNX and BlackBerry. This patch skips two test that expect the section size to be of a certain pixel size. Change-Id: I7869f77fc2b623e091f53e420d1a4fdb3ec30724 Reviewed-by: Bernd Weimer Reviewed-by: Sergio Ahumada --- tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 3e6df0f136..869b335a95 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -621,6 +621,9 @@ void tst_QHeaderView::sectionSize_data() void tst_QHeaderView::sectionSize() { +#if defined Q_OS_QNX + QSKIP("The section size is dpi dependent on QNX"); +#endif QFETCH(QList, boundsCheck); QFETCH(QList, defaultSizes); QFETCH(int, initialDefaultSize); @@ -734,6 +737,9 @@ void tst_QHeaderView::visualIndexAt_data() void tst_QHeaderView::visualIndexAt() { +#if defined Q_OS_QNX + QSKIP("The section size is dpi dependent on QNX"); +#endif QFETCH(QList, hidden); QFETCH(QList, from); QFETCH(QList, to); -- cgit v1.2.3 From 449a0a286841fee4d991b162dc161663092037f3 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 8 Apr 2014 15:38:04 +0300 Subject: Add unhandled Android keys. Sort case values. The following new keys were added: KEYCODE_F1 -- KEYCODE_F12 KEYCODE_NUMPAD_0 -- KEYCODE_NUMPAD_9 KEYCODE_AT KEYCODE_PAGE_UP KEYCODE_PAGE_DOWN KEYCODE_ESCAPE KEYCODE_CTRL_LEFT KEYCODE_CTRL_RIGHT KEYCODE_CAPS_LOCK KEYCODE_SCROLL_LOCK KEYCODE_META_LEFT KEYCODE_META_RIGHT KEYCODE_SYSRQ KEYCODE_BREAK KEYCODE_MOVE_HOME KEYCODE_MOVE_END KEYCODE_MOVE_INSERT KEYCODE_FORWARD KEYCODE_MEDIA_PLAY KEYCODE_MEDIA_PAUSE KEYCODE_NUM_LOCK KEYCODE_NUMPAD_DIVIDE KEYCODE_NUMPAD_MULTIPLY KEYCODE_NUMPAD_SUBTRACT KEYCODE_NUMPAD_ADD KEYCODE_NUMPAD_DOT KEYCODE_NUMPAD_COMMA KEYCODE_NUMPAD_ENTER KEYCODE_NUMPAD_EQUALS KEYCODE_NUMPAD_LEFT_PAREN KEYCODE_NUMPAD_RIGHT_PAREN KEYCODE_BOOKMARK KEYCODE_BRIGHTNESS_DOWN KEYCODE_BRIGHTNESS_UP KEYCODE_MEDIA_AUDIO_TRACK Change-Id: I599e9e46ea720e52004a53747d6b21fc7a44262e Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Christian Stromme --- src/plugins/platforms/android/androidjniinput.cpp | 467 +++++++++++++++------- 1 file changed, 316 insertions(+), 151 deletions(-) diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp index 9efdcad158..760da7a767 100644 --- a/src/plugins/platforms/android/androidjniinput.cpp +++ b/src/plugins/platforms/android/androidjniinput.cpp @@ -47,9 +47,7 @@ #include #include -#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL -# include -#endif +#include using namespace QtAndroid; @@ -277,226 +275,393 @@ namespace QtAndroidInput if (key >= 0x0000001d && key <= 0x00000036) return Qt::Key_A + key - 0x0000001d; + // F1--F12 0x00000083 -- 0x0000008e + if (key >= 0x00000083 && key <= 0x0000008e) + return Qt::Key_F1 + key - 0x00000083; + + // NUMPAD_0--NUMPAD_9 0x00000090 -- 0x00000099 + if (key >= 0x00000090 && key <= 0x00000099) + return Qt::KeypadModifier + Qt::Key_0 + key - 0x00000090; + + // BUTTON_1--KEYCODE_BUTTON_16 0x000000bc -- 0x000000cb + switch (key) { - case 0x00000039: - case 0x0000003a: - return Qt::Key_Alt; + case 0x00000000: // KEYCODE_UNKNOWN + return Qt::Key_unknown; + + case 0x00000001: // KEYCODE_SOFT_LEFT + return Qt::Key_Left; + + case 0x00000002: // KEYCODE_SOFT_RIGHT + return Qt::Key_Right; + + // 0x00000003: // KEYCODE_HOME is never delivered to applications. + + case 0x00000004: // KEYCODE_BACK + return Qt::Key_Back; + + case 0x00000005: // KEYCODE_CALL + return Qt::Key_Call; + + case 0x00000006: // KEYCODE_ENDCALL + return Qt::Key_Hangup; + + // 0--9 0x00000007 -- 0x00000010 + + case 0x00000011: // KEYCODE_STAR + return Qt::Key_Asterisk; + + case 0x00000012: // KEYCODE_POUND + return Qt::Key_NumberSign; + + case 0x00000013: //KEYCODE_DPAD_UP + return Qt::Key_Up; + + case 0x00000014: // KEYCODE_DPAD_DOWN + return Qt::Key_Down; + + case 0x00000015: //KEYCODE_DPAD_LEFT + return Qt::Key_Left; + + case 0x00000016: //KEYCODE_DPAD_RIGHT + return Qt::Key_Right; + + case 0x00000017: // KEYCODE_DPAD_CENTER + return Qt::Key_Enter; + + case 0x00000018: // KEYCODE_VOLUME_UP + return Qt::Key_VolumeUp; + + case 0x00000019: // KEYCODE_VOLUME_DOWN + return Qt::Key_VolumeDown; + + case 0x0000001a: + return Qt::Key_PowerOff; + + case 0x0000001b: // KEYCODE_CAMERA + return Qt::Key_Camera; + + case 0x0000001c: // KEYCODE_CLEAR + return Qt::Key_Clear; + + // A--Z 0x0000001d -- 0x00000036 + + case 0x00000037: // KEYCODE_COMMA + return Qt::Key_Comma; + + case 0x00000038: // KEYCODE_PERIOD + return Qt::Key_Period; + + case 0x00000039: // KEYCODE_ALT_LEFT + case 0x0000003a: // KEYCODE_ALT_RIGHT + return Qt::Key_Alt; + + case 0x0000003b: // KEYCODE_SHIFT_LEFT + case 0x0000003c: // KEYCODE_SHIFT_RIGHT + return Qt::Key_Shift; + + case 0x0000003d: // KEYCODE_TAB + return Qt::Key_Tab; + + case 0x0000003e: // KEYCODE_SPACE + return Qt::Key_Space; + + case 0x0000003f: // KEYCODE_SYM + return Qt::Key_Meta; + + case 0x00000040: // KEYCODE_EXPLORER + return Qt::Key_Explorer; + + case 0x00000041: //KEYCODE_ENVELOPE + return Qt::Key_LaunchMail; + + case 0x00000042: // KEYCODE_ENTER + return Qt::Key_Return; + + case 0x00000043: // KEYCODE_DEL + return Qt::Key_Backspace; + + case 0x00000044: // KEYCODE_GRAVE + return Qt::Key_QuoteLeft; + + case 0x00000045: // KEYCODE_MINUS + return Qt::Key_Minus; + + case 0x00000046: // KEYCODE_EQUALS + return Qt::Key_Equal; + + case 0x00000047: // KEYCODE_LEFT_BRACKET + return Qt::Key_BracketLeft; + + case 0x00000048: // KEYCODE_RIGHT_BRACKET + return Qt::Key_BracketRight; + + case 0x00000049: // KEYCODE_BACKSLASH + return Qt::Key_Backslash; + + case 0x0000004a: // KEYCODE_SEMICOLON + return Qt::Key_Semicolon; + + case 0x0000004b: // KEYCODE_APOSTROPHE + return Qt::Key_Apostrophe; + + case 0x0000004c: // KEYCODE_SLASH + return Qt::Key_Slash; + + case 0x0000004d: // KEYCODE_AT + return Qt::Key_At; + + case 0x0000004e: // KEYCODE_NUM + return Qt::Key_Alt; + + case 0x0000004f: // KEYCODE_HEADSETHOOK + return 0; + + case 0x00000050: // KEYCODE_FOCUS + return Qt::Key_CameraFocus; + + case 0x00000051: // KEYCODE_PLUS + return Qt::Key_Plus; + + case 0x00000052: // KEYCODE_MENU + return Qt::Key_Menu; + + case 0x00000053: // KEYCODE_NOTIFICATION + return 0; - case 0x0000004b: - return Qt::Key_Apostrophe; + case 0x00000054: // KEYCODE_SEARCH + return Qt::Key_Search; - case 0x00000004: // KEYCODE_BACK - return Qt::Key_Back; + case 0x00000055: // KEYCODE_MEDIA_PLAY_PAUSE + return Qt::Key_MediaPlay; - case 0x00000049: - return Qt::Key_Backslash; + case 0x00000056: // KEYCODE_MEDIA_STOP + return Qt::Key_MediaStop; - case 0x00000005: - return Qt::Key_Call; + case 0x00000057: // KEYCODE_MEDIA_NEXT + return Qt::Key_MediaNext; - case 0x0000001b: // KEYCODE_CAMERA - return Qt::Key_Camera; + case 0x00000058: // KEYCODE_MEDIA_PREVIOUS + return Qt::Key_MediaPrevious; - case 0x0000001c: - return Qt::Key_Clear; + case 0x00000059: // KEYCODE_MEDIA_REWIND + return Qt::Key_AudioRewind; - case 0x00000037: - return Qt::Key_Comma; + case 0x0000005a: // KEYCODE_MEDIA_FAST_FORWARD + return Qt::Key_AudioForward; - case 0x00000043: // KEYCODE_DEL - return Qt::Key_Backspace; + case 0x0000005b: // KEYCODE_MUTE + return Qt::Key_MicMute; - case 0x00000017: // KEYCODE_DPAD_CENTER - return Qt::Key_Enter; + case 0x0000005c: // KEYCODE_PAGE_UP + return Qt::Key_PageUp; - case 0x00000014: // KEYCODE_DPAD_DOWN - return Qt::Key_Down; + case 0x0000005d: // KEYCODE_PAGE_DOWN + return Qt::Key_PageDown; - case 0x00000015: //KEYCODE_DPAD_LEFT - return Qt::Key_Left; + case 0x0000005e: // KEYCODE_PICTSYMBOLS + return 0; - case 0x00000016: //KEYCODE_DPAD_RIGHT - return Qt::Key_Right; + case 0x00000060: // KEYCODE_BUTTON_A + case 0x00000061: // KEYCODE_BUTTON_B + case 0x00000062: // KEYCODE_BUTTON_B + case 0x00000063: // KEYCODE_BUTTON_X + case 0x00000064: // KEYCODE_BUTTON_Y + case 0x00000065: // KEYCODE_BUTTON_Z + case 0x00000066: // KEYCODE_BUTTON_L1 + case 0x00000067: // KEYCODE_BUTTON_R1 + case 0x00000068: // KEYCODE_BUTTON_L2 + case 0x00000069: // KEYCODE_BUTTON_R2 + case 0x0000006a: // KEYCODE_BUTTON_THUMBL + case 0x0000006b: // KEYCODE_BUTTON_THUMBR + case 0x0000006c: // KEYCODE_BUTTON_START + case 0x0000006d: // KEYCODE_BUTTON_SELECT + case 0x0000006e: // KEYCODE_BUTTON_MODE + return 0; - case 0x00000013: //KEYCODE_DPAD_UP - return Qt::Key_Up; + case 0x0000006f: // KEYCODE_ESCAPE + return Qt::Key_Escape; - case 0x00000006: //KEYCODE_ENDCALL - return Qt::Key_Hangup; + case 0x00000070: // KEYCODE_FORWARD_DEL + return Qt::Key_Delete; - case 0x00000042: - return Qt::Key_Return; + case 0x00000071: // KEYCODE_CTRL_LEFT + case 0x00000072: // KEYCODE_CTRL_RIGHT + return Qt::Key_Control; - case 0x00000041: //KEYCODE_ENVELOPE - return Qt::Key_LaunchMail; + case 0x00000073: // KEYCODE_CAPS_LOCK + return Qt::Key_CapsLock; - case 0x00000046: - return Qt::Key_Equal; + case 0x00000074: // KEYCODE_SCROLL_LOCK + return Qt::Key_ScrollLock; - case 0x00000040: - return Qt::Key_Explorer; + case 0x00000075: // KEYCODE_META_LEFT + case 0x00000076: // KEYCODE_META_RIGHT + return Qt::Key_Meta; - case 0x00000003: - return Qt::Key_Home; + case 0x00000077: // KEYCODE_FUNCTION + return 0; - case 0x00000047: - return Qt::Key_BracketLeft; + case 0x00000078: // KEYCODE_SYSRQ + return Qt::Key_Print; - case 0x0000005a: // KEYCODE_MEDIA_FAST_FORWARD - return Qt::Key_AudioForward; + case 0x00000079: // KEYCODE_BREAK + return Qt::Key_Pause; - case 0x00000057: - return Qt::Key_MediaNext; + case 0x0000007a: // KEYCODE_MOVE_HOME + return Qt::Key_Home; - case 0x00000055: - return Qt::Key_MediaPlay; + case 0x0000007b: // KEYCODE_MOVE_END + return Qt::Key_End; - case 0x00000058: - return Qt::Key_MediaPrevious; + case 0x0000007c: // KEYCODE_MOVE_INSERT + return Qt::Key_Insert; - case 0x00000059: // KEYCODE_MEDIA_REWIND - return Qt::Key_AudioRewind; + case 0x0000007d: // KEYCODE_FORWARD + return Qt::Key_Forward; - case 0x00000056: - return Qt::Key_MediaStop; + case 0x0000007e: // KEYCODE_MEDIA_PLAY + return Qt::Key_MediaPlay; - case 0x00000052: //KEYCODE_MENU - return Qt::Key_Menu; + case 0x0000007f: // KEYCODE_MEDIA_PAUSE + return Qt::Key_MediaPause; - case 0x00000045: - return Qt::Key_Minus; + case 0x00000080: // KEYCODE_MEDIA_CLOSE + case 0x00000081: // KEYCODE_MEDIA_EJECT + return Qt::Key_Eject; - case 0x0000005b: // KEYCODE_MUTE - return Qt::Key_MicMute; + case 0x00000082: // KEYCODE_MEDIA_RECORD + return Qt::Key_MediaRecord; - case 0x0000004e: - return Qt::Key_NumLock; + // F1--F12 0x00000083 -- 0x0000008e - case 0x00000038: - return Qt::Key_Period; + case 0x0000008f: // KEYCODE_NUM_LOCK + return Qt::Key_NumLock; - case 0x00000051: - return Qt::Key_Plus; + // NUMPAD_0--NUMPAD_9 0x00000090 -- 0x00000099 - case 0x0000001a: - return Qt::Key_PowerOff; + case 0x0000009a: // KEYCODE_NUMPAD_DIVIDE + return Qt::KeypadModifier + Qt::Key_Slash; - case 0x00000048: - return Qt::Key_BracketRight; + case 0x0000009b: // KEYCODE_NUMPAD_MULTIPLY + return Qt::KeypadModifier + Qt::Key_Asterisk; - case 0x00000054: - return Qt::Key_Search; + case 0x0000009c: // KEYCODE_NUMPAD_SUBTRACT + return Qt::KeypadModifier + Qt::Key_Minus; - case 0x0000004a: - return Qt::Key_Semicolon; + case 0x0000009d: // KEYCODE_NUMPAD_ADD + return Qt::KeypadModifier + Qt::Key_Plus; - case 0x0000003b: - case 0x0000003c: - return Qt::Key_Shift; + case 0x0000009e: // KEYCODE_NUMPAD_DOT + return Qt::KeypadModifier + Qt::Key_Period; - case 0x0000004c: - return Qt::Key_Slash; + case 0x0000009f: // KEYCODE_NUMPAD_COMMA + return Qt::KeypadModifier + Qt::Key_Comma; - case 0x00000001: - return Qt::Key_Left; + case 0x000000a0: // KEYCODE_NUMPAD_ENTER + return Qt::Key_Enter; - case 0x00000002: - return Qt::Key_Right; + case 0x000000a1: // KEYCODE_NUMPAD_EQUALS + return Qt::KeypadModifier + Qt::Key_Equal; - case 0x0000003e: - return Qt::Key_Space; + case 0x000000a2: // KEYCODE_NUMPAD_LEFT_PAREN + return Qt::Key_ParenLeft; - case 0x0000003f: // KEYCODE_SYM - return Qt::Key_Meta; + case 0x000000a3: // KEYCODE_NUMPAD_RIGHT_PAREN + return Qt::Key_ParenRight; - case 0x0000003d: - return Qt::Key_Tab; + case 0x000000a4: // KEYCODE_VOLUME_MUTE + return Qt::Key_VolumeMute; - case 0x00000019: - return Qt::Key_VolumeDown; + case 0x000000a5: // KEYCODE_INFO + return Qt::Key_Info; - case 0x000000a4: // KEYCODE_VOLUME_MUTE - return Qt::Key_VolumeMute; + case 0x000000a6: // KEYCODE_CHANNEL_UP + return Qt::Key_ChannelUp; - case 0x00000018: - return Qt::Key_VolumeUp; + case 0x000000a7: // KEYCODE_CHANNEL_DOWN + return Qt::Key_ChannelDown; - case 0x00000011: // KEYCODE_STAR - return Qt::Key_Asterisk; + case 0x000000a8: // KEYCODE_ZOOM_IN + return Qt::Key_ZoomIn; - case 0x00000012: // KEYCODE_POUND - return Qt::Key_NumberSign; + case 0x000000a9: // KEYCODE_ZOOM_OUT + return Qt::Key_ZoomOut; - case 0x00000050: // KEYCODE_FOCUS - return Qt::Key_CameraFocus; + case 0x000000aa: // KEYCODE_TV + case 0x000000ab: // KEYCODE_WINDOW + return 0; - case 0x00000070: // KEYCODE_FORWARD_DEL - return Qt::Key_Delete; + case 0x000000ac: // KEYCODE_GUIDE + return Qt::Key_Guide; - case 0x00000080: // KEYCODE_MEDIA_CLOSE - return Qt::Key_Close; + case 0x000000ad: // KEYCODE_DVR + return 0; - case 0x00000081: // KEYCODE_MEDIA_EJECT - return Qt::Key_Eject; + case 0x000000ae: // KEYCODE_BOOKMARK + return Qt::Key_AddFavorite; - case 0x00000082: // KEYCODE_MEDIA_RECORD - return Qt::Key_MediaRecord; + case 0x000000af: // KEYCODE_CAPTIONS + return Qt::Key_Subtitle; - case 0x000000b7: // KEYCODE_PROG_RED - return Qt::Key_Red; + case 0x000000b0: // KEYCODE_SETTINGS + return Qt::Key_Settings; - case 0x000000b8: // KEYCODE_PROG_GREEN - return Qt::Key_Green; + case 0x000000b1: // KEYCODE_TV_POWER + case 0x000000b2: // KEYCODE_TV_INPUT + case 0x000000b3: // KEYCODE_STB_POWER + case 0x000000b4: // KEYCODE_STB_INPUT + case 0x000000b5: // KEYCODE_AVR_POWER + case 0x000000b6: // KEYCODE_AVR_INPUT + return 0; - case 0x000000b9: // KEYCODE_PROG_YELLOW - return Qt::Key_Yellow; + case 0x000000b7: // KEYCODE_PROG_RED + return Qt::Key_Red; - case 0x000000ba: // KEYCODE_PROG_BLUE - return Qt::Key_Blue; + case 0x000000b8: // KEYCODE_PROG_GREEN + return Qt::Key_Green; - case 0x000000a5: // KEYCODE_INFO - return Qt::Key_Info; + case 0x000000b9: // KEYCODE_PROG_YELLOW + return Qt::Key_Yellow; - case 0x000000a6: // KEYCODE_CHANNEL_UP - return Qt::Key_ChannelUp; + case 0x000000ba: // KEYCODE_PROG_BLUE + return Qt::Key_Blue; - case 0x000000a7: // KEYCODE_CHANNEL_DOWN - return Qt::Key_ChannelDown; + // 0x000000bb: // KEYCODE_APP_SWITCH is not sent by the Android O.S. - case 0x000000a8: // KEYCODE_ZOOM_IN - return Qt::Key_ZoomIn; + // BUTTON_1--KEYCODE_BUTTON_16 0x000000bc -- 0x000000cb - case 0x000000a9: // KEYCODE_ZOOM_OUT - return Qt::Key_ZoomOut; + case 0x000000cc: // KEYCODE_LANGUAGE_SWITCH + case 0x000000cd: // KEYCODE_MANNER_MODE do we need such a thing? + case 0x000000ce: // KEYCODE_3D_MODE + case 0x000000cf: // KEYCODE_CONTACTS + return 0; - case 0x000000ac: // KEYCODE_GUIDE - return Qt::Key_Guide; + case 0x000000d0: // KEYCODE_CALENDAR + return Qt::Key_Calendar; - case 0x000000af: // KEYCODE_CAPTIONS - return Qt::Key_Subtitle; + case 0x000000d1: // KEYCODE_MUSIC + return Qt::Key_Music; - case 0x000000b0: // KEYCODE_SETTINGS - return Qt::Key_Settings; + case 0x000000d2: // KEYCODE_CALCULATOR + return Qt::Key_Calculator; - case 0x000000d0: // KEYCODE_CALENDAR - return Qt::Key_Calendar; + // 0x000000d3 -- 0x000000da some japanese specific keys, someone who understand what is about should check ! - case 0x000000d1: // KEYCODE_MUSIC - return Qt::Key_Music; + // 0x000000db: // KEYCODE_ASSIST not delivered to applications. - case 0x000000d2: // KEYCODE_CALCULATOR - return Qt::Key_Calculator; + case 0x000000dc: // KEYCODE_BRIGHTNESS_DOWN + return Qt::Key_KeyboardBrightnessDown; - case 0x00000000: // KEYCODE_UNKNOWN - return Qt::Key_unknown; + case 0x000000dd: // KEYCODE_BRIGHTNESS_UP + return Qt::Key_KeyboardBrightnessUp; - case 0x00000053: // KEYCODE_NOTIFICATION ?!?!? - case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!? - case 0x00000044: // KEYCODE_GRAVE ?!?!? - return Qt::Key_Any; + case 0x000000de: // KEYCODE_MEDIA_AUDIO_TRACK + return Qt::Key_AudioCycleTrack; - default: - return 0; + default: + qWarning() << "Unhandled key code " << key << "!"; + return 0; } } -- cgit v1.2.3 From 61541404bcf216330cc081964dade9b2427e8491 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 8 Apr 2014 11:49:14 +0200 Subject: Fix crash in qt_try_modal. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-34580 Change-Id: Idc549116fa99aa49ac7c67dcfc76d32ca71f3c76 Reviewed-by: Jan Arve Sæther --- src/widgets/kernel/qapplication_qpa.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index 5a4a4591bf..c68bcc773f 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -93,7 +93,6 @@ bool qt_try_modal(QWidget *widget, QEvent::Type type) return true; bool block_event = false; - bool paint_event = false; switch (type) { #if 0 @@ -113,7 +112,7 @@ bool qt_try_modal(QWidget *widget, QEvent::Type type) break; } - if ((block_event || paint_event) && top->parentWidget() == 0) + if (block_event && top && top->parentWidget() == 0) top->raise(); return !block_event; -- cgit v1.2.3 From 229c98abf0069e181704c6db9043f0cec00eff97 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 8 Apr 2014 11:11:20 +0200 Subject: QWindowsOpenGLContextFormat: Default to version 2. glGetString() returns NULL when no current context exists. Task-number: QTBUG-38063 Change-Id: I5cdb265fb2d74bbc5f3e2c34528909323573b2e1 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/windows/qwindowsglcontext.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index e7e4028079..eaa4eca84e 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -711,6 +711,8 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current() minorDot = version.size(); result.version = (version.mid(0, majorDot).toInt() << 8) + version.mid(majorDot + 1, minorDot - majorDot - 1).toInt(); + } else { + result.version = 0x0200; } result.profile = QSurfaceFormat::NoProfile; if (result.version < 0x0300) { -- cgit v1.2.3 From 1a6410f91f5e5edf11508e19176123b54e474e83 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 1 Apr 2014 12:04:44 +0200 Subject: Change QVERIFY in tst_qnetworkreply to warning. FAIL! : tst_QNetworkReply::ioPostToHttpUploadProgress() 'args.at(0).toLongLong() != sourceFile.size()' returned FALSE. () Task-number: QTBUG-37449 Task-number: QTBUG-24226 Change-Id: Idcc0ceac0332705b1e3a073d40fa8098bea2c9f3 Reviewed-by: Richard J. Moore Reviewed-by: Peter Hartmann --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index fbac7dc77c..0509eb9a77 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -4876,6 +4876,7 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() //test file must be larger than OS socket buffers (~830kB on MacOS 10.6) QFile sourceFile(testDataDir + "/image1.jpg"); QVERIFY(sourceFile.open(QIODevice::ReadOnly)); + const qint64 sourceFileSize = sourceFile.size(); // emulate a minimal http server QTcpServer server; @@ -4900,24 +4901,32 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() QTestEventLoop::instance().enterLoop(5); // some progress should have been made QVERIFY(!spy.isEmpty()); - QList args = spy.last(); + const QList args = spy.last(); QVERIFY(!args.isEmpty()); - QVERIFY(args.at(0).toLongLong() > 0); - // but not everything! - QVERIFY(args.at(0).toLongLong() != sourceFile.size()); + const qint64 bufferedUploadProgress = args.at(0).toLongLong(); + QVERIFY(bufferedUploadProgress > 0); + // but not everything? - Note however, that under CI virtualization, + // particularly on Windows, it frequently happens that the whole file + // is uploaded in one chunk. + if (bufferedUploadProgress == sourceFileSize) { + qWarning() << QDir::toNativeSeparators(sourceFile.fileName()) + << "of" << sourceFileSize << "bytes was uploaded in one go."; + } // set the read buffer to unlimited incomingSocket->setReadBufferSize(0); QTestEventLoop::instance().enterLoop(10); // progress should be finished QVERIFY(!spy.isEmpty()); - QList args3 = spy.last(); + const QList args3 = spy.last(); QVERIFY(!args3.isEmpty()); // More progress than before - QVERIFY(args3.at(0).toLongLong() > args.at(0).toLongLong()); - QCOMPARE(args3.at(0).toLongLong(), args3.at(1).toLongLong()); + const qint64 unbufferedUploadProgress = args3.at(0).toLongLong(); + if (bufferedUploadProgress < sourceFileSize) + QVERIFY(unbufferedUploadProgress > bufferedUploadProgress); + QCOMPARE(unbufferedUploadProgress, args3.at(1).toLongLong()); // And actually finished.. - QCOMPARE(args3.at(0).toLongLong(), sourceFile.size()); + QCOMPARE(unbufferedUploadProgress, sourceFileSize); // after sending this, the QNAM should emit finished() connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); -- cgit v1.2.3 From e38ad9455099a83e2a8619f19ca949bc64ae6f82 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 28 Mar 2014 15:55:31 +0100 Subject: Fix crash when trying to place toolbar into zero-height window. Change QToolBarAreaLayout::item() to return a pointer and check return values in plug(). Task-number: QTBUG-37183 Change-Id: I7029eb9739cbe603460e87d3e5493f116bdb3a89 Reviewed-by: J-P Nurmi --- src/widgets/widgets/qmainwindowlayout.cpp | 12 ++++++---- src/widgets/widgets/qtoolbararealayout.cpp | 38 ++++++++++++++++++------------ src/widgets/widgets/qtoolbararealayout_p.h | 2 +- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 92a1274d7c..c026b79103 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -508,8 +508,11 @@ QLayoutItem *QMainWindowLayoutState::item(const QList &path) int i = path.first(); #ifndef QT_NO_TOOLBAR - if (i == 0) - return toolBarAreaLayout.item(path.mid(1)).widgetItem; + if (i == 0) { + const QToolBarAreaLayoutItem *tbItem = toolBarAreaLayout.item(path.mid(1)); + Q_ASSERT(tbItem); + return tbItem->widgetItem; + } #endif #ifndef QT_NO_DOCKWIDGET @@ -1567,9 +1570,10 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) QList previousPath = layoutState.indexOf(widget); - QLayoutItem *it = layoutState.plug(currentGapPos); + const QLayoutItem *it = layoutState.plug(currentGapPos); + if (!it) + return false; Q_ASSERT(it == widgetItem); - Q_UNUSED(it); if (!previousPath.isEmpty()) layoutState.remove(previousPath); diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp index 5ec76569aa..4591c2ac5f 100644 --- a/src/widgets/widgets/qtoolbararealayout.cpp +++ b/src/widgets/widgets/qtoolbararealayout.cpp @@ -1107,16 +1107,19 @@ void QToolBarAreaLayout::clear() rect = QRect(); } -QToolBarAreaLayoutItem &QToolBarAreaLayout::item(const QList &path) +QToolBarAreaLayoutItem *QToolBarAreaLayout::item(const QList &path) { Q_ASSERT(path.count() == 3); - Q_ASSERT(path.at(0) >= 0 && path.at(0) < QInternal::DockCount); + if (path.at(0) < 0 || path.at(0) >= QInternal::DockCount) + return 0; QToolBarAreaLayoutInfo &info = docks[path.at(0)]; - Q_ASSERT(path.at(1) >= 0 && path.at(1) < info.lines.count()); + if (path.at(1) < 0 || path.at(1) >= info.lines.count()) + return 0; QToolBarAreaLayoutLine &line = info.lines[path.at(1)]; - Q_ASSERT(path.at(2) >= 0 && path.at(2) < line.toolBarItems.count()); - return line.toolBarItems[path.at(2)]; + if (path.at(2) < 0 || path.at(2) >= line.toolBarItems.count()) + return 0; + return &(line.toolBarItems[path.at(2)]); } QRect QToolBarAreaLayout::itemRect(const QList &path) const @@ -1132,23 +1135,28 @@ QRect QToolBarAreaLayout::itemRect(const QList &path) const QLayoutItem *QToolBarAreaLayout::plug(const QList &path) { - QToolBarAreaLayoutItem &item = this->item(path); - Q_ASSERT(item.gap); - Q_ASSERT(item.widgetItem != 0); - item.gap = false; - return item.widgetItem; + QToolBarAreaLayoutItem *item = this->item(path); + if (!item) { + qWarning() << Q_FUNC_INFO << "No item at" << path; + return 0; + } + Q_ASSERT(item->gap); + Q_ASSERT(item->widgetItem != 0); + item->gap = false; + return item->widgetItem; } QLayoutItem *QToolBarAreaLayout::unplug(const QList &path, QToolBarAreaLayout *other) { //other needs to be update as well Q_ASSERT(path.count() == 3); - QToolBarAreaLayoutItem &item = this->item(path); + QToolBarAreaLayoutItem *item = this->item(path); + Q_ASSERT(item); //update the leading space here QToolBarAreaLayoutInfo &info = docks[path.at(0)]; QToolBarAreaLayoutLine &line = info.lines[path.at(1)]; - if (item.size != pick(line.o, item.realSizeHint())) { + if (item->size != pick(line.o, item->realSizeHint())) { //the item doesn't have its default size //so we'll give this to the next item int newExtraSpace = 0; @@ -1185,9 +1193,9 @@ QLayoutItem *QToolBarAreaLayout::unplug(const QList &path, QToolBarAreaLayo } } - Q_ASSERT(!item.gap); - item.gap = true; - return item.widgetItem; + Q_ASSERT(!item->gap); + item->gap = true; + return item->widgetItem; } static QRect unpackRect(uint geom0, uint geom1, bool *floating) diff --git a/src/widgets/widgets/qtoolbararealayout_p.h b/src/widgets/widgets/qtoolbararealayout_p.h index ec7d1f26f1..6ba9768467 100644 --- a/src/widgets/widgets/qtoolbararealayout_p.h +++ b/src/widgets/widgets/qtoolbararealayout_p.h @@ -232,7 +232,7 @@ public: void remove(const QList &path); void remove(QLayoutItem *item); void clear(); - QToolBarAreaLayoutItem &item(const QList &path); + QToolBarAreaLayoutItem *item(const QList &path); QRect itemRect(const QList &path) const; QLayoutItem *plug(const QList &path); QLayoutItem *unplug(const QList &path, QToolBarAreaLayout *other); -- cgit v1.2.3 From 71de8c0df57ddee94da71fab4a613f1df003a18f Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 9 Apr 2014 05:25:58 -0700 Subject: Only define Q_COMPILER_INITIALIZER_LISTS for MSVC 12 SP 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nested initialization is broken before SP2, so just disable the whole feature as tst_qvector crashes(release)/fails(debug) Done-with: Jedrzej Nowacki Task-number: QTBUG-38186 Change-Id: I9c5c9e55c75854fc1f05a59fab2ac7dce9b37fbb Reviewed-by: Jędrzej Nowacki Reviewed-by: Friedemann Kleint --- src/corelib/global/qcompilerdetection.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 00f209ad6d..950647004a 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -827,13 +827,18 @@ # define Q_COMPILER_DELEGATING_CONSTRUCTORS # define Q_COMPILER_EXPLICIT_CONVERSIONS # define Q_COMPILER_NONSTATIC_MEMBER_INIT -# define Q_COMPILER_INITIALIZER_LISTS +// implemented, but nested initialization fails (eg tst_qvector): http://connect.microsoft.com/VisualStudio/feedback/details/800364/initializer-list-calls-object-destructor-twice +// #define Q_COMPILER_INITIALIZER_LISTS // implemented in principle, but has a bug that makes it unusable: http://connect.microsoft.com/VisualStudio/feedback/details/802058/c-11-unified-initialization-fails-with-c-style-arrays // #define Q_COMPILER_UNIFORM_INIT # define Q_COMPILER_RAW_STRINGS # define Q_COMPILER_TEMPLATE_ALIAS # define Q_COMPILER_VARIADIC_TEMPLATES # endif /* VC 12 */ +# if _MSC_FULL_VER >= 180030324 // VC 12 SP 2 RC +# define Q_COMPILER_INITIALIZER_LISTS +# endif /* VC 12 SP 2 RC */ + #endif /* Q_CC_MSVC */ #ifdef __cplusplus -- cgit v1.2.3 From 814a1c7b2b940cdf6b1716406b26063576ac0d95 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sun, 6 Apr 2014 12:38:52 +0100 Subject: Support for DH and ECDH key exchange for QSslSocket servers Despite supporting DH and ECDH key exchange as a client, Qt did not provide any default parameters which prevented them being used as a server. A future change should allow the user to control the parameters used, but these defaults should be okay for most users. [ChangeLog][Important Behavior Changes] Support for DH and ECDH key exchange cipher suites when acting as an SSL server has been made possible. This change means the you can now implement servers that offer forward-secrecy using Qt. Task-number: QTBUG-20666 Change-Id: I469163900e4313da9d2d0c3e1e5e47ef46320b17 Reviewed-by: Daniel Molkentin Reviewed-by: Peter Hartmann --- src/network/ssl/qsslcontext.cpp | 59 +++++++++++++++++++ src/network/ssl/qsslsocket_openssl_symbols.cpp | 10 ++++ src/network/ssl/qsslsocket_openssl_symbols_p.h | 11 ++++ .../auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 67 ++++++++++++++++++++++ 4 files changed, 147 insertions(+) diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp index 1634ba0649..9c68218062 100644 --- a/src/network/ssl/qsslcontext.cpp +++ b/src/network/ssl/qsslcontext.cpp @@ -55,6 +55,53 @@ QT_BEGIN_NAMESPACE extern int q_X509Callback(int ok, X509_STORE_CTX *ctx); extern QString getErrorsFromOpenSsl(); +// Default DH params +// 1024-bit MODP Group with 160-bit Prime Order Subgroup +// From RFC 5114 +static unsigned const char dh1024_p[]={ + 0xB1,0x0B,0x8F,0x96,0xA0,0x80,0xE0,0x1D,0xDE,0x92,0xDE,0x5E, + 0xAE,0x5D,0x54,0xEC,0x52,0xC9,0x9F,0xBC,0xFB,0x06,0xA3,0xC6, + 0x9A,0x6A,0x9D,0xCA,0x52,0xD2,0x3B,0x61,0x60,0x73,0xE2,0x86, + 0x75,0xA2,0x3D,0x18,0x98,0x38,0xEF,0x1E,0x2E,0xE6,0x52,0xC0, + 0x13,0xEC,0xB4,0xAE,0xA9,0x06,0x11,0x23,0x24,0x97,0x5C,0x3C, + 0xD4,0x9B,0x83,0xBF,0xAC,0xCB,0xDD,0x7D,0x90,0xC4,0xBD,0x70, + 0x98,0x48,0x8E,0x9C,0x21,0x9A,0x73,0x72,0x4E,0xFF,0xD6,0xFA, + 0xE5,0x64,0x47,0x38,0xFA,0xA3,0x1A,0x4F,0xF5,0x5B,0xCC,0xC0, + 0xA1,0x51,0xAF,0x5F,0x0D,0xC8,0xB4,0xBD,0x45,0xBF,0x37,0xDF, + 0x36,0x5C,0x1A,0x65,0xE6,0x8C,0xFD,0xA7,0x6D,0x4D,0xA7,0x08, + 0xDF,0x1F,0xB2,0xBC,0x2E,0x4A,0x43,0x71 +}; + +static unsigned const char dh1024_g[]={ + 0xA4,0xD1,0xCB,0xD5,0xC3,0xFD,0x34,0x12,0x67,0x65,0xA4,0x42, + 0xEF,0xB9,0x99,0x05,0xF8,0x10,0x4D,0xD2,0x58,0xAC,0x50,0x7F, + 0xD6,0x40,0x6C,0xFF,0x14,0x26,0x6D,0x31,0x26,0x6F,0xEA,0x1E, + 0x5C,0x41,0x56,0x4B,0x77,0x7E,0x69,0x0F,0x55,0x04,0xF2,0x13, + 0x16,0x02,0x17,0xB4,0xB0,0x1B,0x88,0x6A,0x5E,0x91,0x54,0x7F, + 0x9E,0x27,0x49,0xF4,0xD7,0xFB,0xD7,0xD3,0xB9,0xA9,0x2E,0xE1, + 0x90,0x9D,0x0D,0x22,0x63,0xF8,0x0A,0x76,0xA6,0xA2,0x4C,0x08, + 0x7A,0x09,0x1F,0x53,0x1D,0xBF,0x0A,0x01,0x69,0xB6,0xA2,0x8A, + 0xD6,0x62,0xA4,0xD1,0x8E,0x73,0xAF,0xA3,0x2D,0x77,0x9D,0x59, + 0x18,0xD0,0x8B,0xC8,0x85,0x8F,0x4D,0xCE,0xF9,0x7C,0x2A,0x24, + 0x85,0x5E,0x6E,0xEB,0x22,0xB3,0xB2,0xE5 +}; + +static DH *get_dh1024() +{ + DH *dh = q_DH_new(); + if (!dh) + return 0; + + dh->p = q_BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0); + dh->g = q_BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0); + if (!dh->p || !dh->g) { + q_DH_free(dh); + return 0; + } + + return dh; +} + QSslContext::QSslContext() : ctx(0), pkey(0), @@ -261,6 +308,18 @@ init_context: if (!configuration.sessionTicket().isEmpty()) sslContext->setSessionASN1(configuration.sessionTicket()); + // Set temp DH params + DH *dh = 0; + dh = get_dh1024(); + q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh); + q_DH_free(dh); + + // Set temp ECDH params + EC_KEY *ecdh = 0; + ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh); + q_EC_KEY_free(ecdh); + return sslContext; } diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 79bce22b0d..01c0f6f810 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -361,6 +361,11 @@ DEFINEFUNC3(void, SSL_CTX_set_next_proto_select_cb, SSL_CTX *s, s, DEFINEFUNC3(void, SSL_get0_next_proto_negotiated, const SSL *s, s, const unsigned char **data, data, unsigned *len, len, return, DUMMYARG) #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... +DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return 0, return) +DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG) +DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return 0, return) +DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return 0, return) +DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG) #define RESOLVEFUNC(func) \ if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \ @@ -835,6 +840,11 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(SSL_CTX_set_next_proto_select_cb) RESOLVEFUNC(SSL_get0_next_proto_negotiated) #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... + RESOLVEFUNC(DH_new) + RESOLVEFUNC(DH_free) + RESOLVEFUNC(BN_bin2bn) + RESOLVEFUNC(EC_KEY_new_by_curve_name) + RESOLVEFUNC(EC_KEY_free) symbolsResolved = true; delete libs.first; diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 500fe9493b..1e68fdd6c2 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -427,6 +427,17 @@ int q_X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); X509 *q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +// Diffie-Hellman support +DH *q_DH_new(); +void q_DH_free(DH *dh); +BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +#define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh) + +// EC Diffie-Hellman support +EC_KEY *q_EC_KEY_new_by_curve_name(int nid); +void q_EC_KEY_free(EC_KEY *ecdh); +#define q_SSL_CTX_set_tmp_ecdh(ctx, ecdh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_ECDH, 0, (char *)ecdh) + #define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) #define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) #ifdef SSLEAY_MACROS diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index ded3966992..baaf21e6bb 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -192,6 +192,8 @@ private slots: void resume(); void qtbug18498_peek(); void qtbug18498_peek2(); + void dhServer(); + void ecdhServer(); void setEmptyDefaultConfiguration(); // this test should be last static void exitLoop() @@ -1004,6 +1006,7 @@ public: QString m_keyFile; QString m_certFile; QString m_interFile; + QString ciphers; protected: void incomingConnection(qintptr socketDescriptor) @@ -1037,6 +1040,10 @@ protected: socket->setLocalCertificateChain(localCert + interCert); } + if (!ciphers.isEmpty()) { + socket->setCiphers(ciphers); + } + QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState)); QVERIFY(!socket->peerAddress().isNull()); QVERIFY(socket->peerPort() != 0); @@ -2665,6 +2672,66 @@ void tst_QSslSocket::qtbug18498_peek2() QVERIFY(client->waitForDisconnected(5000)); } +void tst_QSslSocket::dhServer() +{ + if (!QSslSocket::supportsSsl()) { + qWarning("SSL not supported, skipping test"); + return; + } + + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + SslServer server; + server.ciphers = QLatin1String("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA"); + QVERIFY(server.listen()); + + QEventLoop loop; + QTimer::singleShot(5000, &loop, SLOT(quit())); + + QSslSocketPtr client(new QSslSocket); + socket = client.data(); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit())); + connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(ignoreErrorSlot())); + connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit())); + + client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); + + loop.exec(); + QVERIFY(client->state() == QAbstractSocket::ConnectedState); +} + +void tst_QSslSocket::ecdhServer() +{ + if (!QSslSocket::supportsSsl()) { + qWarning("SSL not supported, skipping test"); + return; + } + + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + SslServer server; + server.ciphers = QLatin1String("ECDHE-RSA-AES128-SHA"); + QVERIFY(server.listen()); + + QEventLoop loop; + QTimer::singleShot(5000, &loop, SLOT(quit())); + + QSslSocketPtr client(new QSslSocket); + socket = client.data(); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit())); + connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(ignoreErrorSlot())); + connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit())); + + client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); + + loop.exec(); + QVERIFY(client->state() == QAbstractSocket::ConnectedState); +} + void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, as it has some side effects { // used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265 -- cgit v1.2.3 From cf439ae331b4f14517a04e7bb05757f8044afbdb Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 9 Apr 2014 18:24:24 +0200 Subject: QNX: Fix QCompleter autotest The tests expect a home folder which usually is not present on QNX Change-Id: I44f548a95f14414c0db6f752fd115696069a7b90 Reviewed-by: Sergio Ahumada --- tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp index 4ba4cffb78..fd2a82886c 100644 --- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp @@ -611,7 +611,7 @@ void tst_QCompleter::directoryModel_data() QTest::newRow("(/u)") << "/u" << "" << "Users" << "/Users"; #else QTest::newRow("()") << "" << "" << "/" << "/"; -#if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_OS_HPUX) +#if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_OS_HPUX) && !defined(Q_OS_QNX) QTest::newRow("(/h)") << "/h" << "" << "home" << "/home"; #endif QTest::newRow("(/et)") << "/et" << "" << "etc" << "/etc"; @@ -657,7 +657,7 @@ void tst_QCompleter::fileSystemModel_data() // QTest::newRow("(/d)") << "/d" << "" << "Developer" << "/Developer"; #else QTest::newRow("()") << "" << "" << "/" << "/"; -#if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_OS_HPUX) +#if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_OS_HPUX) && !defined(Q_OS_QNX) QTest::newRow("(/h)") << "/h" << "" << "home" << "/home"; #endif QTest::newRow("(/et)") << "/et" << "" << "etc" << "/etc"; -- cgit v1.2.3 From 8a96e0d83c6493e66502b6c500d8fdf6eb0090ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 8 Apr 2014 16:31:18 +0000 Subject: Fix a typo in QBitArray documentation Task-number: QTBUG-37839 Change-Id: Id55d2d606b93f7f9e58ef423544e42b548035ee3 Reviewed-by: Friedemann Kleint --- .../doc/snippets/code/src_corelib_tools_qbitarray.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp index e8ec95f4ee..4b2916a619 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp @@ -115,7 +115,7 @@ a[2] = a[0] ^ a[1]; QBitArray a(3); QBitArray b(2); a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ] -b[0] = 1; b[1] = 0; // b: [ 1, 1 ] +b[0] = 1; b[1] = 1; // b: [ 1, 1 ] a &= b; // a: [ 1, 0, 0 ] //! [8] @@ -124,7 +124,7 @@ a &= b; // a: [ 1, 0, 0 ] QBitArray a(3); QBitArray b(2); a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ] -b[0] = 1; b[1] = 0; // b: [ 1, 1 ] +b[0] = 1; b[1] = 1; // b: [ 1, 1 ] a |= b; // a: [ 1, 1, 1 ] //! [9] @@ -133,7 +133,7 @@ a |= b; // a: [ 1, 1, 1 ] QBitArray a(3); QBitArray b(2); a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ] -b[0] = 1; b[1] = 0; // b: [ 1, 1 ] +b[0] = 1; b[1] = 1; // b: [ 1, 1 ] a ^= b; // a: [ 0, 1, 1 ] //! [10] @@ -151,7 +151,7 @@ QBitArray a(3); QBitArray b(2); QBitArray c; a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ] -b[0] = 1; b[1] = 0; // b: [ 1, 1 ] +b[0] = 1; b[1] = 1; // b: [ 1, 1 ] c = a & b; // c: [ 1, 0, 0 ] //! [12] @@ -161,7 +161,7 @@ QBitArray a(3); QBitArray b(2); QBitArray c; a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ] -b[0] = 1; b[1] = 0; // b: [ 1, 1 ] +b[0] = 1; b[1] = 1; // b: [ 1, 1 ] c = a | b; // c: [ 1, 1, 1 ] //! [13] @@ -171,6 +171,6 @@ QBitArray a(3); QBitArray b(2); QBitArray c; a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ] -b[0] = 1; b[1] = 0; // b: [ 1, 1 ] +b[0] = 1; b[1] = 1; // b: [ 1, 1 ] c = a ^ b; // c: [ 0, 1, 1 ] //! [14] -- cgit v1.2.3 From 4f31b01e36570201143b962e4586b5a88c03b911 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 9 Apr 2014 11:48:57 +0200 Subject: Doc: Fix template code for unordered lists The CSS for unordered lists placed a nested list vertically too close to its parent list item. This commit fixes the issue. Task-number: QTBUG-38217 Change-Id: Ia5003f2aab197f455ed5bbea2e1ee2e6475aaffe Reviewed-by: Jerome Pasion --- doc/global/template/style/offline.css | 2 +- doc/global/template/style/online.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/global/template/style/offline.css b/doc/global/template/style/offline.css index bfa086284f..c993a07d47 100644 --- a/doc/global/template/style/offline.css +++ b/doc/global/template/style/offline.css @@ -464,7 +464,7 @@ List */ ul { - padding-bottom: 2px + margin-top: 10px; } li { diff --git a/doc/global/template/style/online.css b/doc/global/template/style/online.css index d105a6fd55..0dc01d396b 100644 --- a/doc/global/template/style/online.css +++ b/doc/global/template/style/online.css @@ -348,7 +348,7 @@ List */ ul { - padding-bottom: 2px + margin-top: 10px; } li { -- cgit v1.2.3 From 4e0c9fbb8f1db2750455fddb9a9b88386c26903e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 9 Apr 2014 13:49:30 +0200 Subject: fix typo in qmake source file list the effect of this is negligible, as this list is only used for dependency scanning. Change-Id: Iae9fc73c8633cfc8217bc90014498d9635d53ad0 Reviewed-by: Robin Burchell Reviewed-by: Joerg Bornemann --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 4d8c280bba..89c2318d82 100755 --- a/configure +++ b/configure @@ -3708,7 +3708,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; EXTRA_SRCS="\"\$(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp\" \ \"\$(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp\" \ \"\$(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp\" \ - \"\$(SOURCE_PATH)/src/corelib/tools/qlocal_unix.cpp\"" + \"\$(SOURCE_PATH)/src/corelib/tools/qlocale_unix.cpp\"" EXEEXT= fi if [ "$BUILD_ON_MAC" = "yes" ]; then -- cgit v1.2.3 From 4255ba40ab073afcf2a095b135883612859af4c2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Apr 2014 22:17:40 +0200 Subject: automatically link plugins belonging to qt modules when building static apps the plugins already declare which modules they belong to. additionally, we allow plugins to declare which modules they "extend" - e.g., while the Quick accessibility plugin belongs to Gui's 'accessiblity' type, it makes no sense to link it unless Quick is actually linked. finally, it is possible to manually override the plugins which are linked for a particular type, by setting QTPLUGIN. (to '-' if no plugins of this type should be linked at all). Task-number: QTBUG-35195 Change-Id: I8273d167a046eb3f3c1c584dc6e3798212a2fa31 Reviewed-by: Fawzi Mohamed Reviewed-by: Richard Moe Gustavsen Reviewed-by: Joerg Bornemann --- mkspecs/features/qt.prf | 34 +++++++++++++++++++++++++++++- mkspecs/features/qt_module_pris.prf | 6 +++++- mkspecs/features/qt_plugin.prf | 4 +++- src/plugins/accessible/widgets/widgets.pro | 1 + 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index fb83e59e65..cf6d66d1a0 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -73,10 +73,11 @@ wince*:static:gui { QTLIB += qmenu_wce.res } -# static builds: link qml import plugins into the app. qt_module_deps = $$QT $$QT_PRIVATE qt_module_deps = $$replace(qt_module_deps, -private$, _private) qt_module_deps = $$resolve_depends(qt_module_deps, "QT.") + +# static builds: link qml import plugins into the app. contains(qt_module_deps, qml): \ contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan { # run qmlimportscanner @@ -162,6 +163,37 @@ contains(qt_module_deps, qml): \ } } +contains(TEMPLATE, .*app) { + autoplugs = + for (qtmod, qt_module_deps) { + for (ptype, QT.$${qtmod}.plugin_types) { + isEmpty(QTPLUGIN.$$ptype) { + for (plug, QT_PLUGINS) { + equals(QT_PLUGIN.$${plug}.TYPE, $$ptype) { + for (dep, QT_PLUGIN.$${plug}.EXTENDS) { + !contains(qt_module_deps, $$dep) { + plug = + break() + } + } + autoplugs += $$plug + } + } + } else { + plug = $$eval(QTPLUGIN.$$ptype) + !equals(plug, -): \ + autoplugs += $$plug + } + } + } + manualplugs = $$QTPLUGIN + manualplugs -= $$autoplugs + QTPLUGIN -= $$manualplugs + !isEmpty(QTPLUGIN): \ + warning("Redundant entries in QTPLUGIN: $$QTPLUGIN") + QTPLUGIN = $$manualplugs $$autoplugs +} + QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN contains(QT_CONFIG, static) { QT_PLUGIN_VERIFY += QTPLUGIN diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf index 900ade9b6e..f31bc38c75 100644 --- a/mkspecs/features/qt_module_pris.prf +++ b/mkspecs/features/qt_module_pris.prf @@ -70,6 +70,10 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri module_config = "QT.$${MODULE_ID}.CONFIG = $$MODULE_CONFIG" else: \ module_config = + !isEmpty(MODULE_PLUGIN_TYPES): \ + module_plugtypes = "QT.$${MODULE_ID}.plugin_types = $$replace(MODULE_PLUGIN_TYPES, /.*$, )" + else: \ + module_plugtypes = !no_module_headers:!minimal_syncqt { MODULE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME MODULE_PRIVATE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME/$$VERSION \ @@ -100,7 +104,7 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri "QT.$${MODULE_ID}.plugins = \$\$QT_MODULE_PLUGIN_BASE" \ "QT.$${MODULE_ID}.imports = \$\$QT_MODULE_IMPORT_BASE" \ "QT.$${MODULE_ID}.qml = \$\$QT_MODULE_QML_BASE" \ - $$join(MODULE_PLUGIN_TYPES, " ", "QT.$${MODULE_ID}.plugin_types = ") + $$module_plugtypes MODULE_PRI_CONT += \ "QT.$${MODULE_ID}.depends =$$join(MODULE_DEPENDS, " ", " ")" \ $$module_rundep \ diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index ba12b9c1cd..5efd55582d 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -32,7 +32,9 @@ CONFIG(static, static|shared) { !build_pass { MODULE_PRI_CONT = \ "QT_PLUGIN.$${MODULE}.TYPE = $$PLUGIN_TYPE" \ - "QT_PLUGIN.$${MODULE}.CLASS_NAME = $$PLUGIN_CLASS_NAME" + "QT_PLUGIN.$${MODULE}.EXTENDS = $$PLUGIN_EXTENDS" \ + "QT_PLUGIN.$${MODULE}.CLASS_NAME = $$PLUGIN_CLASS_NAME" \ + "QT_PLUGINS += $$MODULE" write_file($$MODULE_PRI, MODULE_PRI_CONT)|error("Aborting.") } diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro index aff60d9781..c6af6d3f71 100644 --- a/src/plugins/accessible/widgets/widgets.pro +++ b/src/plugins/accessible/widgets/widgets.pro @@ -1,6 +1,7 @@ TARGET = qtaccessiblewidgets PLUGIN_TYPE = accessible +PLUGIN_EXTENDS = widgets PLUGIN_CLASS_NAME = AccessibleFactory load(qt_plugin) -- cgit v1.2.3 From 06e4676871143acf99380dfe9331563d106d3c50 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 4 Apr 2014 16:49:26 +0200 Subject: make QTPLUGIN work in prefix builds for plugins outside qtbase this means creating forwarding pris also for plugins. unlike for qt modules, we don't actually populate the .PATH unless it we are making a prefix build (and thus expecting it to be outside the regular location). Change-Id: Id836821cddec8d5f53d0708ae001e8eaa13cc71b Reviewed-by: Joerg Bornemann --- mkspecs/features/qt.prf | 7 ++++++- mkspecs/features/qt_plugin.prf | 31 +++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index cf6d66d1a0..5968a8a4ff 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -241,7 +241,12 @@ for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) { # Only link against plugin in static builds isEqual(QT_CURRENT_VERIFY, QTPLUGIN): { - !isEmpty(QT_PLUGINPATH): LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/$$QT_PLUGINPATH + !isEmpty(QT_PLUGINPATH) { + plugpath = $$eval(QT_PLUGIN.$${QTPLUG}.PATH) + isEmpty(plugpath): \ + plugpath = $$[QT_INSTALL_PLUGINS/get] + LIBS *= -L$$plugpath/$$QT_PLUGINPATH + } LIBS += $$QT_LINKAGE # if the plugin is linked statically there is no need to deploy it DEPLOYMENT_PLUGIN -= $$QT_CURRENT_VERIFY diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index 5efd55582d..c020bd2767 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -27,7 +27,13 @@ tool_plugin { CONFIG(static, static|shared) { isEmpty(MODULE): MODULE = $$basename(TARGET) - MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_plugin_$${MODULE}.pri + mod_work_pfx = $$MODULE_QMAKE_OUTDIR/mkspecs/modules + force_independent: \ + mod_inst_pfx = $$MODULE_QMAKE_OUTDIR/mkspecs/modules-inst + else: \ + mod_inst_pfx = $$mod_work_pfx + MODULE_PRI = $$mod_inst_pfx/qt_plugin_$${MODULE}.pri + MODULE_FWD_PRI = $$mod_work_pfx/qt_plugin_$${MODULE}.pri !build_pass { MODULE_PRI_CONT = \ @@ -35,8 +41,29 @@ CONFIG(static, static|shared) { "QT_PLUGIN.$${MODULE}.EXTENDS = $$PLUGIN_EXTENDS" \ "QT_PLUGIN.$${MODULE}.CLASS_NAME = $$PLUGIN_CLASS_NAME" \ "QT_PLUGINS += $$MODULE" - write_file($$MODULE_PRI, MODULE_PRI_CONT)|error("Aborting.") + MODULE_PRI_FILES = $$MODULE_PRI + + force_independent { + + # Create a forwarding module .pri file + MODULE_FWD_PRI_CONT = \ + "QT_PLUGIN.$${MODULE}.PATH = $$MODULE_BASE_OUTDIR/plugins" \ + "include($$MODULE_PRI)" + write_file($$MODULE_FWD_PRI, MODULE_FWD_PRI_CONT)|error("Aborting.") + touch($$MODULE_FWD_PRI, $$MODULE_PRI) + MODULE_PRI_FILES += $$MODULE_FWD_PRI + + } + + # Then, inject the new module into the current cache state + !contains(QMAKE_INTERNAL_INCLUDED_FILES, $$MODULE_FWD_PRI): \ # before the actual include()! + cache(QMAKE_INTERNAL_INCLUDED_FILES, add transient, MODULE_PRI_FILES) + include($$MODULE_FWD_PRI) + for(var, $$list(TYPE EXTENDS CLASS_NAME PATH)): \ + defined(QT_PLUGIN.$${MODULE}.$$var, var): \ + cache(QT_PLUGIN.$${MODULE}.$$var, transient) + cache(QT_PLUGINS, transient) } pritarget.path = $$[QT_HOST_DATA]/mkspecs/modules -- cgit v1.2.3 From 08672adb97c0707c513850a27aaec59327874260 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Apr 2014 22:19:01 +0200 Subject: make cmake registration of qt plugins make use of PLUGIN_EXTENDS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit instead of assigning plugins to the first module which claims the whole type, try to assign it to a module which the plugin claims to extend. as we are getting stricter in that go, somebody needs to claim the 'generic', 'platformthemes', and 'platforminputcontexts' plugin types. the natural claimant is QtGui. however, as we don't want to auto-link any of these plugins, make them all claim that they extend a non-existing module. QtGui also claims 'iconengines' plugins. the 'printsupport' plugins are also claimed by the respective module. Change-Id: I7af7c16089f137b8d4a4ed93d1577bd85815c87b Reviewed-by: Jørgen Lind Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/features/create_cmake.prf | 21 ++++++++++++++------- src/gui/gui.pro | 4 ++++ src/plugins/generic/evdevkeyboard/evdevkeyboard.pro | 1 + src/plugins/generic/evdevmouse/evdevmouse.pro | 1 + src/plugins/generic/evdevtablet/evdevtablet.pro | 1 + src/plugins/generic/evdevtouch/evdevtouch.pro | 1 + src/plugins/generic/meego/meego.pro | 1 + src/plugins/generic/tslib/tslib.pro | 1 + .../platforminputcontexts/compose/compose.pro | 1 + src/plugins/platforminputcontexts/ibus/ibus.pro | 1 + src/plugins/platformthemes/gtk2/gtk2.pro | 1 + src/printsupport/printsupport.pro | 3 +++ 12 files changed, 30 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index 82e2812f3b..ac5fe22d75 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -111,15 +111,22 @@ if(build_all|CONFIG(debug, debug|release)): CMAKE_DEBUG_TYPE = debug if(build_all|CONFIG(release, debug|release)): CMAKE_RELEASE_TYPE = release contains(CONFIG, plugin) { - PLUGIN_MODULE_NAME = - for (mod, QT_MODULES) { - types = $$replace(QT.$${mod}.plugin_types, /.*$, ) - contains(types, $$PLUGIN_TYPE) { - PLUGIN_MODULE_NAME = $$mod - break() + !isEmpty(PLUGIN_EXTENDS):!equals(PLUGIN_EXTENDS, -) { + count(PLUGIN_EXTENDS, 1, greaterThan): \ + error("Plugin declares to extend multiple modules. We don't handle that ...") + PLUGIN_MODULE_NAME = $$PLUGIN_EXTENDS + } else { + PLUGIN_MODULE_NAME = + for (mod, QT_MODULES) { + contains(QT.$${mod}.plugin_types, $$PLUGIN_TYPE) { + !isEmpty(PLUGIN_MODULE_NAME): \ + error("Multiple modules claim plugin type '$$PLUGIN_TYPE' ($$mod, in addition to $$PLUGIN_MODULE_NAME)") + PLUGIN_MODULE_NAME = $$mod + break() + } } + isEmpty(PLUGIN_MODULE_NAME): error("No module claims plugin type '$$PLUGIN_TYPE'") } - isEmpty(PLUGIN_MODULE_NAME): return() CMAKE_MODULE_NAME = $$cmakeModuleName($$PLUGIN_MODULE_NAME) diff --git a/src/gui/gui.pro b/src/gui/gui.pro index c5262501ac..6af692984a 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -10,6 +10,10 @@ QMAKE_DOCS = $$PWD/doc/qtgui.qdocconf MODULE_PLUGIN_TYPES = \ platforms \ + platformthemes \ + platforminputcontexts \ + generic \ + iconengines \ imageformats # This is here only because the platform plugin is no module, obviously. diff --git a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro index 281515145f..101ea30bcc 100644 --- a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro +++ b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro @@ -1,6 +1,7 @@ TARGET = qevdevkeyboardplugin PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QEvdevKeyboardPlugin load(qt_plugin) diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro index 9a3cc839cc..57a67ead8d 100644 --- a/src/plugins/generic/evdevmouse/evdevmouse.pro +++ b/src/plugins/generic/evdevmouse/evdevmouse.pro @@ -1,6 +1,7 @@ TARGET = qevdevmouseplugin PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QEvdevMousePlugin load(qt_plugin) diff --git a/src/plugins/generic/evdevtablet/evdevtablet.pro b/src/plugins/generic/evdevtablet/evdevtablet.pro index ee3fbb3ec1..8ffc0db84d 100644 --- a/src/plugins/generic/evdevtablet/evdevtablet.pro +++ b/src/plugins/generic/evdevtablet/evdevtablet.pro @@ -1,6 +1,7 @@ TARGET = qevdevtabletplugin PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QEvdevTabletPlugin load(qt_plugin) diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro index 3d1c481c36..1f4d1b7e93 100644 --- a/src/plugins/generic/evdevtouch/evdevtouch.pro +++ b/src/plugins/generic/evdevtouch/evdevtouch.pro @@ -1,6 +1,7 @@ TARGET = qevdevtouchplugin PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QEvdevTouchScreenPlugin load(qt_plugin) diff --git a/src/plugins/generic/meego/meego.pro b/src/plugins/generic/meego/meego.pro index c428517cd5..4baaa43a4c 100644 --- a/src/plugins/generic/meego/meego.pro +++ b/src/plugins/generic/meego/meego.pro @@ -1,6 +1,7 @@ TARGET = qmeegointegration PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QMeeGoIntegrationPlugin load(qt_plugin) diff --git a/src/plugins/generic/tslib/tslib.pro b/src/plugins/generic/tslib/tslib.pro index 035857bb73..bc05efcc32 100644 --- a/src/plugins/generic/tslib/tslib.pro +++ b/src/plugins/generic/tslib/tslib.pro @@ -1,6 +1,7 @@ TARGET = qtslibplugin PLUGIN_TYPE = generic +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QTsLibPlugin load(qt_plugin) diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro index 7182c458fc..10e50a7a7e 100644 --- a/src/plugins/platforminputcontexts/compose/compose.pro +++ b/src/plugins/platforminputcontexts/compose/compose.pro @@ -1,6 +1,7 @@ TARGET = composeplatforminputcontextplugin PLUGIN_TYPE = platforminputcontexts +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin load(qt_plugin) diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro index 75a5b5838f..401be6d42f 100644 --- a/src/plugins/platforminputcontexts/ibus/ibus.pro +++ b/src/plugins/platforminputcontexts/ibus/ibus.pro @@ -1,6 +1,7 @@ TARGET = ibusplatforminputcontextplugin PLUGIN_TYPE = platforminputcontexts +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QIbusPlatformInputContextPlugin load(qt_plugin) diff --git a/src/plugins/platformthemes/gtk2/gtk2.pro b/src/plugins/platformthemes/gtk2/gtk2.pro index bb02192f91..73c156f82b 100644 --- a/src/plugins/platformthemes/gtk2/gtk2.pro +++ b/src/plugins/platformthemes/gtk2/gtk2.pro @@ -1,6 +1,7 @@ TARGET = qgtk2 PLUGIN_TYPE = platformthemes +PLUGIN_EXTENDS = - PLUGIN_CLASS_NAME = QGtk2ThemePlugin load(qt_plugin) diff --git a/src/printsupport/printsupport.pro b/src/printsupport/printsupport.pro index a92d36f7bc..b32ba91c07 100644 --- a/src/printsupport/printsupport.pro +++ b/src/printsupport/printsupport.pro @@ -4,6 +4,9 @@ QT = core-private gui-private widgets-private MODULE_CONFIG = needs_printsupport_plugin DEFINES += QT_NO_USING_NAMESPACE +MODULE_PLUGIN_TYPES = \ + printsupport + QMAKE_DOCS = $$PWD/doc/qtprintsupport.qdocconf load(qt_module) -- cgit v1.2.3 From b2a6c9ec3ef37f571aca2ce1c48d346d4f09a305 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 8 Apr 2014 22:46:17 +0200 Subject: Fix tst_QListWidget::task217070_scrollbarsAdjusted() QMacStyle::styleHint(SH_ScrollBar_Transient) wants either a style object or the widget argument in order to return correct values. Change-Id: I2fdef0820334fa66e076a4734eb2a30c722c841c Reviewed-by: Jens Bache-Wiig --- tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index e02ab0064c..5474043cf6 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -1575,7 +1575,7 @@ void tst_QListWidget::task217070_scrollbarsAdjusted() for(int f=150; f>90 ; f--) { v.resize(f,100); QTest::qWait(30); - QVERIFY(vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient) || vbar->isVisible()); + QVERIFY(vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar) || vbar->isVisible()); //the horizontal scrollbar must not be visible. QVERIFY(!hbar->isVisible()); } -- cgit v1.2.3 From 0f2acaf1cb6be5290f64842667e60b6675b467c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 31 Mar 2014 12:19:20 +0200 Subject: Cocoa: Update unified toolbar area on toolbar hide Add setContentBorderAreaEnabled() which us used to enable or disable an area. Used together with registerContentBorderArea() this allows changing the border area geometry and enabled status independently. Add section to the QToolBar show/hide event handler which calls setContentBorderAreaEnabled(). Make sure QToolBar and QToolBarLayout uses the same identifier - the QToolBar object pointer. Rename enableContentBorderArea -> setContentBorderEnabled. The "ContentBorder" is now the entire unified toolbar area while "ContentBorderArea"s are the sub-areas covered by toolbars. Change-Id: I339f381a50856e048ae40e7ffadd6a8a510c4994 Reviewed-by: Gabriel de Dietrich --- .../platforms/cocoa/qcocoanativeinterface.h | 13 +++-- .../platforms/cocoa/qcocoanativeinterface.mm | 20 ++++++-- src/plugins/platforms/cocoa/qcocoawindow.h | 7 ++- src/plugins/platforms/cocoa/qcocoawindow.mm | 59 ++++++++++++---------- src/widgets/widgets/qmainwindow.cpp | 6 +-- src/widgets/widgets/qtoolbar.cpp | 18 +++++++ src/widgets/widgets/qtoolbarlayout.cpp | 4 +- 7 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index efdd433d8f..0318c52628 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -133,16 +133,19 @@ private: // deregisters. static void registerTouchWindow(QWindow *window, bool enable); - // Request a unified title and toolbar look for the window. + // Enable the unified title and toolbar area for a window. + static void setContentBorderEnabled(QWindow *window, bool enable); + + // Set the size of the unified title and toolbar area. static void setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness); - // Request a unified title and toolbar look for the window by registering - // an area. Multiple callers can register areas and the platform plugin + // Set the size for a unified toolbar content border area. + // Multiple callers can register areas and the platform plugin // will extend the "unified" area to cover them. static void registerContentBorderArea(QWindow *window, quintptr identifer, int upper, int lower); - // Enable the unified title and toolbar area. - static void enableContentBorderArea(QWindow *window, bool enable); + // Enables or disiables a content border area. + static void setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable); // Sets a NSToolbar instance for the given QWindow. The // toolbar will be attached to the native NSWindow when diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index d6a5be8d52..b18c586212 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -127,8 +127,10 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderThickness); if (resource.toLower() == "registercontentborderarea") return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerContentBorderArea); - if (resource.toLower() == "enablecontentborderarea") - return NativeResourceForIntegrationFunction(QCocoaNativeInterface::enableContentBorderArea); + if (resource.toLower() == "setcontentborderareaenabled") + return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderAreaEnabled); + if (resource.toLower() == "setcontentborderenabled") + return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderEnabled); if (resource.toLower() == "setnstoolbar") return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar); @@ -301,14 +303,24 @@ void QCocoaNativeInterface::registerContentBorderArea(QWindow *window, quintptr cocoaWindow->registerContentBorderArea(identifier, upper, lower); } -void QCocoaNativeInterface::enableContentBorderArea(QWindow *window, bool enable) +void QCocoaNativeInterface::setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable) { if (!window) return; QCocoaWindow *cocoaWindow = static_cast(window->handle()); if (cocoaWindow) - cocoaWindow->enableContentBorderArea(enable); + cocoaWindow->setContentBorderAreaEnabled(identifier, enable); +} + +void QCocoaNativeInterface::setContentBorderEnabled(QWindow *window, bool enable) +{ + if (!window) + return; + + QCocoaWindow *cocoaWindow = static_cast(window->handle()); + if (cocoaWindow) + cocoaWindow->setContentBorderEnabled(enable); } void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index b7a6a14d4a..d8eb0ed0bd 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -211,7 +211,8 @@ public: void registerTouch(bool enable); void setContentBorderThickness(int topThickness, int bottomThickness); void registerContentBorderArea(quintptr identifier, int upper, int lower); - void enableContentBorderArea(bool enable); + void setContentBorderAreaEnabled(quintptr identifier, bool enable); + void setContentBorderEnabled(bool enable); void applyContentBorderThickness(NSWindow *window); void updateNSToolbar(); @@ -289,7 +290,8 @@ public: // for QNSView NSApplicationPresentationOptions m_presentationOptions; struct BorderRange { - BorderRange(int u, int l) : upper(u), lower(l) { } + BorderRange(quintptr i, int u, int l) : identifier(i), upper(u), lower(l) { } + quintptr identifier; int upper; int lower; bool operator<(BorderRange const& right) const { @@ -297,6 +299,7 @@ public: // for QNSView } }; QHash m_contentBorderAreas; // identifer -> uppper/lower + QHash m_enabledContentBorderAreas; // identifer -> enabled state (true/false) }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index b07b5e33be..515e2bf132 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1596,28 +1596,17 @@ void QCocoaWindow::setContentBorderThickness(int topThickness, int bottomThickne void QCocoaWindow::registerContentBorderArea(quintptr identifier, int upper, int lower) { - m_contentBorderAreas.insert(identifier, BorderRange(upper, lower)); - - // Find consecutive registered border areas, starting from the top. - QList ranges = m_contentBorderAreas.values(); - std::sort(ranges.begin(), ranges.end()); - m_topContentBorderThickness = 0; - foreach (BorderRange range, ranges) { - // Is this sub-range adjacent to or overlaping the - // existing total border area range? If so merge - // it into the total range, - if (range.upper <= (m_topContentBorderThickness + 1)) - m_topContentBorderThickness = qMax(m_topContentBorderThickness, range.lower); - else - break; - } + m_contentBorderAreas.insert(identifier, BorderRange(identifier, upper, lower)); + applyContentBorderThickness(m_nsWindow); +} - m_bottomContentBorderThickness = 0; // (not supported) - if (m_drawContentBorderGradient) - applyContentBorderThickness(m_nsWindow); +void QCocoaWindow::setContentBorderAreaEnabled(quintptr identifier, bool enable) +{ + m_enabledContentBorderAreas.insert(identifier, enable); + applyContentBorderThickness(m_nsWindow); } -void QCocoaWindow::enableContentBorderArea(bool enable) +void QCocoaWindow::setContentBorderEnabled(bool enable) { m_drawContentBorderGradient = enable; applyContentBorderThickness(m_nsWindow); @@ -1633,17 +1622,33 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window) return; } - [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask]; + // Find consecutive registered border areas, starting from the top. + QList ranges = m_contentBorderAreas.values(); + std::sort(ranges.begin(), ranges.end()); + int effectiveTopContentBorderThickness = m_topContentBorderThickness; + foreach (BorderRange range, ranges) { + // Skip disiabled ranges (typically hidden tool bars) + if (!m_enabledContentBorderAreas.value(range.identifier, false)) + continue; - if (m_topContentBorderThickness > 0) { - [window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMaxYEdge]; - [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge]; + // Is this sub-range adjacent to or overlaping the + // existing total border area range? If so merge + // it into the total range, + if (range.upper <= (effectiveTopContentBorderThickness + 1)) + effectiveTopContentBorderThickness = qMax(effectiveTopContentBorderThickness, range.lower); + else + break; } - if (m_bottomContentBorderThickness > 0) { - [window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMinYEdge]; - [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge]; - } + int effectiveBottomContentBorderThickness = m_bottomContentBorderThickness; + + [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask]; + + [window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge]; + [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge]; + + [window setContentBorderThickness:effectiveBottomContentBorderThickness forEdge:NSMinYEdge]; + [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge]; } void QCocoaWindow::updateNSToolbar() diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 1d0268a244..90cfb1d7cb 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -1513,12 +1513,12 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set) QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); QPlatformNativeInterface::NativeResourceForIntegrationFunction function = - nativeInterface->nativeResourceFunctionForIntegration("enableContentBorderArea"); + nativeInterface->nativeResourceFunctionForIntegration("setContentBorderEnabled"); if (!function) return; // Not Cocoa platform plugin. - typedef void (*EnableContentBorderAreaFunction)(QWindow *window, bool enable); - (reinterpret_cast(function))(window()->windowHandle(), set); + typedef void (*SetContentBorderEnabledFunction)(QWindow *window, bool enable); + (reinterpret_cast(function))(window()->windowHandle(), set); } #endif diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index 53b77c34da..3fd615c3c7 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -1040,6 +1040,21 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup) return false; } +#ifdef Q_OS_OSX +static void enableMacToolBar(QToolBar *toolbar, bool enable) +{ + QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface(); + QPlatformNativeInterface::NativeResourceForIntegrationFunction function = + nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled"); + if (!function) + return; // Not Cocoa platform plugin. + + typedef void (*SetContentBorderAreaEnabledFunction)(QWindow *window, void *identifier, bool enabled); + (reinterpret_cast(function))(toolbar->window()->windowHandle(), toolbar, enable); +} +#endif + + /*! \reimp */ bool QToolBar::event(QEvent *event) { @@ -1062,6 +1077,9 @@ bool QToolBar::event(QEvent *event) // fallthrough intended case QEvent::Show: d->toggleViewAction->setChecked(event->type() == QEvent::Show); +#ifdef Q_OS_OSX + enableMacToolBar(this, event->type() == QEvent::Show); +#endif emit visibilityChanged(event->type() == QEvent::Show); break; case QEvent::ParentChange: diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp index 020d180778..efd33da7fc 100644 --- a/src/widgets/widgets/qtoolbarlayout.cpp +++ b/src/widgets/widgets/qtoolbarlayout.cpp @@ -369,9 +369,9 @@ void QToolBarLayout::updateMacBorderMetrics() typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, void *identifier, int upper, int lower); if (mainWindow->toolBarArea(tb) == Qt::TopToolBarArea) { - (reinterpret_cast(function))(tb->window()->windowHandle(), this, upper.y(), lower.y()); + (reinterpret_cast(function))(tb->window()->windowHandle(), tb, upper.y(), lower.y()); } else { - (reinterpret_cast(function))(tb->window()->windowHandle(), this, 0, 0); + (reinterpret_cast(function))(tb->window()->windowHandle(), tb, 0, 0); } #endif } -- cgit v1.2.3 From 3876a05adf08b3ab5a921f9c5bf81a22baace93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 10 Jan 2014 15:41:20 +0100 Subject: Mac: Implement unified toolbar look for QTabBar Extend the unified title and toolbar gradient to tabs in document mode that are adjacent unified tool bars. Change the updateMacBorderMetrics() function to register the tab bar geometry and visibility status with the Cocoa platform plugin. The Cocoa platform plugin will then merge this area with other registered areas if possible. Add QCocoaNativeInterface::testContentBorderPosition(). This function tests whether the given point is within the unified title and toolbar area. Use testContentBorderPosition() in QMacStyle to enable code paths that skips drawing the QToolBar bottom separator line and paints the active tab background with transparent pixels to make the background gradient visible. Change-Id: I2b70f9bb0c2c59af053a691a7df538f958783dab Reviewed-by: Gabriel de Dietrich --- .../platforms/cocoa/qcocoanativeinterface.h | 4 ++ .../platforms/cocoa/qcocoanativeinterface.mm | 13 ++++ src/plugins/platforms/cocoa/qcocoawindow.h | 1 + src/plugins/platforms/cocoa/qcocoawindow.mm | 6 ++ src/widgets/styles/qmacstyle_mac.mm | 57 +++++++++++++---- src/widgets/widgets/qtabbar.cpp | 71 +++++++++++++--------- src/widgets/widgets/qtabbar_p.h | 1 + 7 files changed, 112 insertions(+), 41 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index 0318c52628..54e45a1d99 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -147,6 +147,10 @@ private: // Enables or disiables a content border area. static void setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable); + // Returns true if the given coordinate is inside the current + // content border. + static bool testContentBorderPosition(QWindow *window, int position); + // Sets a NSToolbar instance for the given QWindow. The // toolbar will be attached to the native NSWindow when // that is created; diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index b18c586212..e09c31231d 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -133,6 +133,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderEnabled); if (resource.toLower() == "setnstoolbar") return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar); + if (resource.toLower() == "testcontentborderposition") + return NativeResourceForIntegrationFunction(QCocoaNativeInterface::testContentBorderPosition); return 0; } @@ -332,4 +334,15 @@ void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar) cocoaWindow->updateNSToolbar(); } +bool QCocoaNativeInterface::testContentBorderPosition(QWindow *window, int position) +{ + if (!window) + return false; + + QCocoaWindow *cocoaWindow = static_cast(window->handle()); + if (cocoaWindow) + return cocoaWindow->testContentBorderAreaPosition(position); + return false; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index d8eb0ed0bd..7a01835d5b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -213,6 +213,7 @@ public: void registerContentBorderArea(quintptr identifier, int upper, int lower); void setContentBorderAreaEnabled(quintptr identifier, bool enable); void setContentBorderEnabled(bool enable); + bool testContentBorderAreaPosition(int position) const; void applyContentBorderThickness(NSWindow *window); void updateNSToolbar(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 515e2bf132..5a4ac9b2cc 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1665,6 +1665,12 @@ void QCocoaWindow::updateNSToolbar() [m_nsWindow setShowsToolbarButton:YES]; } +bool QCocoaWindow::testContentBorderAreaPosition(int position) const +{ + return m_nsWindow && m_drawContentBorderGradient && + 0 <= position && position < [m_nsWindow contentBorderThicknessForEdge: NSMaxYEdge]; +} + qreal QCocoaWindow::devicePixelRatio() const { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 2d8489f47f..d35dd16f85 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -179,6 +179,19 @@ static bool isVerticalTabs(const QTabBar::Shape shape) { || shape == QTabBar::TriangularWest); } +static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY) +{ + QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); + QPlatformNativeInterface::NativeResourceForIntegrationFunction function = + nativeInterface->nativeResourceFunctionForIntegration("testContentBorderPosition"); + if (!function) + return false; // Not Cocoa platform plugin. + + typedef bool (*TestContentBorderPositionFunction)(QWindow *, int); + return (reinterpret_cast(function))(window, windowY); +} + + void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected) { // draw background circle @@ -239,7 +252,7 @@ QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect) return tabRect; } -void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt) +void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt, bool isUnified) { QRect r = tabOpt->rect; p->translate(tabOpt->rect.x(), tabOpt->rect.y()); @@ -256,7 +269,12 @@ void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt) QRect rect(1, 0, width - 2, height); // fill body - if (active) { + if (tabOpt->documentMode && isUnified) { + p->save(); + p->setCompositionMode(QPainter::CompositionMode_Source); + p->fillRect(rect, QColor(Qt::transparent)); + p->restore(); + } else if (active) { int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0; p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d)); } else { @@ -3733,8 +3751,14 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter if (const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast(opt)) { if (tabOptV3->documentMode) { p->save(); - // QRect tabRect = tabOptV3->rect; - drawTabShape(p, tabOptV3); + bool isUnified = false; + if (w) { + QRect tabRect = tabOptV3->rect; + QPoint windowTabStart = w->mapTo(w->window(), tabRect.topLeft()); + isUnified = isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowTabStart.y()); + } + + drawTabShape(p, tabOptV3, isUnified); p->restore(); return; } @@ -4442,15 +4466,22 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter p->fillRect(opt->rect, Qt::transparent); p->restore(); - // drow horizontal sepearator line at toolBar bottom. - SInt32 margin; - GetThemeMetric(kThemeMetricSeparatorSize, &margin); - CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin); - HIThemeSeparatorDrawInfo separatorDrawInfo; - separatorDrawInfo.version = 0; - separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive; - QMacCGContext cg(p); - HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal); + // Drow a horizontal sepearator line at the toolBar bottom if the "unified" area ends here. + // There might be additional toolbars or other widgets such as tab bars in document + // mode below. Determine this by making a unified toolbar area test for the row below + // this toolbar. + QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft()); + bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1); + if (isEndOfUnifiedArea) { + SInt32 margin; + GetThemeMetric(kThemeMetricSeparatorSize, &margin); + CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin); + HIThemeSeparatorDrawInfo separatorDrawInfo; + separatorDrawInfo.version = 0; + separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive; + QMacCGContext cg(p); + HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal); + } break; } } diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index b47d65f561..789ec2f6fd 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -56,6 +56,9 @@ #ifndef QT_NO_ACCESSIBILITY #include "qaccessible.h" #endif +#ifdef Q_OS_OSX +#include +#endif #include "qdebug.h" #include "private/qtabbar_p.h" @@ -80,35 +83,44 @@ inline static bool verticalTabs(QTabBar::Shape shape) void QTabBarPrivate::updateMacBorderMetrics() { -#if defined(Q_WS_MAC) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { - Q_Q(QTabBar); - ::HIContentBorderMetrics metrics; - - // TODO: get metrics to preserve the bottom value - // TODO: test tab bar position - - OSWindowRef window = qt_mac_window_for(q); - - // push base line separator down to the client are so we can paint over it (Carbon) - metrics.top = (documentMode && q->isVisible()) ? 1 : 0; - metrics.bottom = 0; - metrics.left = 0; - metrics.right = 0; - qt_mac_updateContentBorderMetricts(window, metrics); - // In Cocoa we need to keep track of the drawRect method. - // If documentMode is enabled we need to change it, unless - // a toolbar is present. - // Notice that all the information is kept in the window, - // that's why we get the private widget for it instead of - // the private widget for this widget. - QWidgetPrivate *privateWidget = qt_widget_private(q->window()); - if(privateWidget) - privateWidget->changeMethods = documentMode; - // Since in Cocoa there is no simple way to remove the baseline, so we just ask the - // top level to do the magic for us. - privateWidget->syncUnifiedMode(); +#if defined(Q_OS_OSX) + Q_Q(QTabBar); + // Extend the unified title and toolbar area to cover the tab bar iff + // 1) the tab bar is in document mode + // 2) the tab bar is directly below an "unified" area. + // The extending itself is done in the Cocoa platform plugin and Mac style, + // this function registers geometry and visibility state for the tab bar. + + // Calculate geometry + int upper, lower; + if (documentMode) { + QPoint windowPos = q->mapTo(q->window(), QPoint(0,0)); + upper = windowPos.y(); + int tabStripHeight = q->tabSizeHint(0).height(); + int pixelTweak = -3; + lower = upper + tabStripHeight + pixelTweak; + } else { + upper = 0; + lower = 0; } + + QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); + quintptr identifier = reinterpret_cast(q); + + // Set geometry + QPlatformNativeInterface::NativeResourceForIntegrationFunction function = + nativeInterface->nativeResourceFunctionForIntegration("registerContentBorderArea"); + if (!function) + return; // Not Cocoa platform plugin. + typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, quintptr identifier, int upper, int lower); + (reinterpret_cast(function))(q->window()->windowHandle(), identifier, upper, lower); + + // Set visibility state + function = nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled"); + if (!function) + return; + typedef void (*SetContentBorderAreaEnabledFunction)(QWindow *window, quintptr identifier, bool enable); + (reinterpret_cast(function))(q->window()->windowHandle(), identifier, q->isVisible()); #endif } @@ -1502,6 +1514,9 @@ bool QTabBar::event(QEvent *event) || (!d->rightB->isHidden() && d->rightB->geometry().contains(pos)); if (!isEventInCornerButtons) emit tabBarDoubleClicked(tabAt(pos)); + } else if (event->type() == QEvent::Move) { + d->updateMacBorderMetrics(); + return QWidget::event(event); } return QWidget::event(event); } diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h index b7b6998ca3..3228308bc6 100644 --- a/src/widgets/widgets/qtabbar_p.h +++ b/src/widgets/widgets/qtabbar_p.h @@ -182,6 +182,7 @@ public: void layoutWidgets(int start = 0); void layoutTab(int index); void updateMacBorderMetrics(); + bool isTabInMacUnifiedToolbarArea() const; void setupMovableTab(); void makeVisible(int index); -- cgit v1.2.3 From 63e33bfdab52b33665a4f53128fa4d447d5ab946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 2 Apr 2014 09:12:20 +0200 Subject: OS X: Add more text editing key bindings. ctrl + K : Cut ctrl + Y : Paste ctrl + F : Cursor right ctrl + B : Cursor left ctrl + N : Cursor down ctrl + P : Cursor up ctrl + V : Cursor next page ctrl + O : Insert line separator (ctrl as in the key, not Qt::CTRL) These are low-priority (0) key sequences. Add them to the end of each StandardKey range and change the priority of an existing item to 1 where it makes sense. Task-number: QTBUG-32837 Change-Id: Id321e6c6ad4277d729b27297a1de66c4628e4201 Reviewed-by: Gabriel de Dietrich --- src/gui/kernel/qkeysequence.cpp | 16 ++++++++-------- src/gui/kernel/qplatformtheme.cpp | 26 +++++++++++++++++--------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 4569457a20..59cdabbc0f 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -238,9 +238,9 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \li SaveAs \li \li Ctrl+Shift+S \li \li Ctrl+Shift+S \row \li New \li Ctrl+N \li Ctrl+N \li Ctrl+N \li Ctrl+N \row \li Delete \li Del \li Del, Meta+D \li Del, Ctrl+D \li Del, Ctrl+D - \row \li Cut \li Ctrl+X, Shift+Del \li Ctrl+X \li Ctrl+X, F20, Shift+Del \li Ctrl+X, F20, Shift+Del + \row \li Cut \li Ctrl+X, Shift+Del \li Ctrl+X, Meta+K \li Ctrl+X, F20, Shift+Del \li Ctrl+X, F20, Shift+Del \row \li Copy \li Ctrl+C, Ctrl+Ins \li Ctrl+C \li Ctrl+C, F16, Ctrl+Ins \li Ctrl+C, F16, Ctrl+Ins - \row \li Paste \li Ctrl+V, Shift+Ins \li Ctrl+V \li Ctrl+V, F18, Shift+Ins \li Ctrl+V, F18, Shift+Ins + \row \li Paste \li Ctrl+V, Shift+Ins \li Ctrl+V, Meta+Y \li Ctrl+V, F18, Shift+Ins \li Ctrl+V, F18, Shift+Ins \row \li Preferences \li \li Ctrl+, \li \li \row \li Undo \li Ctrl+Z, Alt+Backspace \li Ctrl+Z \li Ctrl+Z, F14 \li Ctrl+Z, F14 \row \li Redo \li Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \li Ctrl+Shift+Z \li Ctrl+Shift+Z \li Ctrl+Shift+Z @@ -263,13 +263,13 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \li Bold \li Ctrl+B \li Ctrl+B \li Ctrl+B \li Ctrl+B \row \li Italic \li Ctrl+I \li Ctrl+I \li Ctrl+I \li Ctrl+I \row \li Underline \li Ctrl+U \li Ctrl+U \li Ctrl+U \li Ctrl+U - \row \li MoveToNextChar \li Right \li Right \li Right \li Right - \row \li MoveToPreviousChar \li Left \li Left \li Left \li Left + \row \li MoveToNextChar \li Right \li Right, Meta+F \li Right \li Right + \row \li MoveToPreviousChar \li Left \li Left, Meta+B \li Left \li Left \row \li MoveToNextWord \li Ctrl+Right \li Alt+Right \li Ctrl+Right \li Ctrl+Right \row \li MoveToPreviousWord \li Ctrl+Left \li Alt+Left \li Ctrl+Left \li Ctrl+Left - \row \li MoveToNextLine \li Down \li Down \li Down \li Down - \row \li MoveToPreviousLine \li Up \li Up \li Up \li Up - \row \li MoveToNextPage \li PgDown \li PgDown, Alt+PgDown, Meta+Down, Meta+PgDown\li PgDown \li PgDown + \row \li MoveToNextLine \li Down \li Down, Meta+N \li Down \li Down + \row \li MoveToPreviousLine \li Up \li Up, Meta+P \li Up \li Up + \row \li MoveToNextPage \li PgDown \li PgDown, Alt+PgDown, Meta+Down, Meta+PgDown, Meta+V \li PgDown \li PgDown \row \li MoveToPreviousPage \li PgUp \li PgUp, Alt+PgUp, Meta+Up, Meta+PgUp \li PgUp \li PgUp \row \li MoveToStartOfLine \li Home \li Ctrl+Left, Meta+Left \li Home \li Home \row \li MoveToEndOfLine \li End \li Ctrl+Right, Meta+Right \li End, Ctrl+E \li End, Ctrl+E @@ -296,7 +296,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \li DeleteEndOfLine \li (none) \li (none) \li Ctrl+K \li Ctrl+K \row \li DeleteCompleteLine \li (none) \li (none) \li Ctrl+U \li Ctrl+U \row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter - \row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter \li Shift+Enter \li Shift+Enter + \row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter, Meta+O \li Shift+Enter \li Shift+Enter \endtable Note that, since the key sequences used for the standard shortcuts differ diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index 05ab2f15ba..d3d3d3c222 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -178,12 +178,13 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, KB_Win | KB_X11}, {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, KB_All}, {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, KB_All}, - {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, KB_Mac}, {QKeySequence::Delete, 0, Qt::CTRL | Qt::Key_D, KB_X11}, //emacs (line edit only) {QKeySequence::Delete, 1, Qt::Key_Delete, KB_All}, + {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, KB_Mac}, {QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, KB_All}, {QKeySequence::Cut, 0, Qt::SHIFT | Qt::Key_Delete, KB_Win | KB_X11}, //## Check if this should work on mac {QKeySequence::Cut, 0, Qt::Key_F20, KB_X11}, //Cut on sun keyboards + {QKeySequence::Cut, 0, Qt::META | Qt::Key_K, KB_Mac}, {QKeySequence::Copy, 0, Qt::CTRL | Qt::Key_Insert, KB_X11 | KB_Win}, {QKeySequence::Copy, 1, Qt::CTRL | Qt::Key_C, KB_All}, {QKeySequence::Copy, 0, Qt::Key_F16, KB_X11}, //Copy on sun keyboards @@ -191,6 +192,7 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::Paste, 1, Qt::CTRL | Qt::Key_V, KB_All}, {QKeySequence::Paste, 0, Qt::SHIFT | Qt::Key_Insert, KB_Win | KB_X11}, {QKeySequence::Paste, 0, Qt::Key_F18, KB_X11}, //Paste on sun keyboards + {QKeySequence::Paste, 0, Qt::META | Qt::Key_Y, KB_Mac}, {QKeySequence::Undo, 0, Qt::ALT | Qt::Key_Backspace, KB_Win}, {QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, KB_All}, {QKeySequence::Undo, 0, Qt::Key_F14, KB_X11}, //Undo on sun keyboards @@ -241,16 +243,21 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::Bold, 1, Qt::CTRL | Qt::Key_B, KB_All}, {QKeySequence::Italic, 0, Qt::CTRL | Qt::Key_I, KB_All}, {QKeySequence::Underline, 1, Qt::CTRL | Qt::Key_U, KB_All}, - {QKeySequence::MoveToNextChar, 0, Qt::Key_Right, KB_All}, - {QKeySequence::MoveToPreviousChar, 0, Qt::Key_Left, KB_All}, + {QKeySequence::MoveToNextChar, 1, Qt::Key_Right, KB_All}, + {QKeySequence::MoveToNextChar, 0, Qt::META | Qt::Key_F, KB_Mac}, + {QKeySequence::MoveToPreviousChar, 1, Qt::Key_Left, KB_All}, + {QKeySequence::MoveToPreviousChar, 0, Qt::META | Qt::Key_B, KB_Mac}, {QKeySequence::MoveToNextWord, 0, Qt::ALT | Qt::Key_Right, KB_Mac}, {QKeySequence::MoveToNextWord, 0, Qt::CTRL | Qt::Key_Right, KB_Win | KB_X11}, {QKeySequence::MoveToPreviousWord, 0, Qt::ALT | Qt::Key_Left, KB_Mac}, {QKeySequence::MoveToPreviousWord, 0, Qt::CTRL | Qt::Key_Left, KB_Win | KB_X11}, - {QKeySequence::MoveToNextLine, 0, Qt::Key_Down, KB_All}, - {QKeySequence::MoveToPreviousLine, 0, Qt::Key_Up, KB_All}, + {QKeySequence::MoveToNextLine, 1, Qt::Key_Down, KB_All}, + {QKeySequence::MoveToNextLine, 0, Qt::META | Qt::Key_N, KB_Mac}, + {QKeySequence::MoveToPreviousLine, 1, Qt::Key_Up, KB_All}, + {QKeySequence::MoveToPreviousLine, 0, Qt::META | Qt::Key_P, KB_Mac}, {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, KB_Mac}, {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, KB_Mac}, + {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_V, KB_Mac}, {QKeySequence::MoveToNextPage, 0, Qt::ALT | Qt::Key_PageDown, KB_Mac }, {QKeySequence::MoveToNextPage, 1, Qt::Key_PageDown, KB_All}, {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, KB_Mac}, @@ -265,9 +272,9 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::MoveToEndOfLine, 0, Qt::Key_End, KB_Win | KB_X11}, {QKeySequence::MoveToEndOfLine, 0, Qt::CTRL + Qt::Key_E, KB_X11}, {QKeySequence::MoveToStartOfBlock, 0, Qt::META | Qt::Key_A, KB_Mac}, - {QKeySequence::MoveToStartOfBlock, 0, Qt::ALT | Qt::Key_Up, KB_Mac}, //mac only + {QKeySequence::MoveToStartOfBlock, 1, Qt::ALT | Qt::Key_Up, KB_Mac}, //mac only {QKeySequence::MoveToEndOfBlock, 0, Qt::META | Qt::Key_E, KB_Mac}, - {QKeySequence::MoveToEndOfBlock, 0, Qt::ALT | Qt::Key_Down, KB_Mac}, //mac only + {QKeySequence::MoveToEndOfBlock, 1, Qt::ALT | Qt::Key_Down, KB_Mac}, //mac only {QKeySequence::MoveToStartOfDocument, 1, Qt::CTRL | Qt::Key_Up, KB_Mac}, {QKeySequence::MoveToStartOfDocument, 0, Qt::CTRL | Qt::Key_Home, KB_Win | KB_X11}, {QKeySequence::MoveToStartOfDocument, 0, Qt::Key_Home, KB_Mac}, @@ -290,10 +297,10 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, KB_Mac}, {QKeySequence::SelectEndOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Mac }, {QKeySequence::SelectEndOfLine, 0, Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11}, + {QKeySequence::SelectStartOfBlock, 1, Qt::ALT | Qt::SHIFT | Qt::Key_Up, KB_Mac}, //mac only {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, KB_Mac}, - {QKeySequence::SelectStartOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Up, KB_Mac}, //mac only + {QKeySequence::SelectEndOfBlock, 1, Qt::ALT | Qt::SHIFT | Qt::Key_Down, KB_Mac}, //mac only {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, KB_Mac}, - {QKeySequence::SelectEndOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Down, KB_Mac}, //mac only {QKeySequence::SelectStartOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Up, KB_Mac}, {QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11}, {QKeySequence::SelectStartOfDocument, 0, Qt::SHIFT | Qt::Key_Home, KB_Mac}, @@ -311,6 +318,7 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Return, KB_Mac}, {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, KB_All}, {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, KB_All}, + {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_O, KB_Mac}, {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_Gnome | KB_Mac}, {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, KB_Mac}, {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_Gnome | KB_KDE | KB_Mac}, -- cgit v1.2.3 From 1a6011e09f6378e177426d5b1bb783419faea02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 21 Mar 2014 11:36:55 +0100 Subject: QTextImageHandler: Load @2x images on retina Look for and load "@2x" image versions. Adjust getPixmap/ImageSize to take the image devicePxielRatio into account. Use doc->documentLayout()->paintDevice() to get the target window devicePixelRatio (like the existing DPI-based scaling). In practice this pointer may/ will be null, fall back to qApp->devicePixelRatio as usual. Task-number: QTBUG-36383 Change-Id: Ib5e113b67242b5a9b3410272f2183a76a60bc773 Reviewed-by: Gabriel de Dietrich --- src/gui/text/qtextimagehandler.cpp | 42 +++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index 9704f7a9dc..02a1091506 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -42,7 +42,7 @@ #include "qtextimagehandler_p.h" -#include +#include #include #include #include @@ -52,6 +52,21 @@ QT_BEGIN_NAMESPACE +static QString resolve2xFile(const QString &fileName, qreal targetDevicePixelRatio) +{ + if (targetDevicePixelRatio <= 1.0) + return fileName; + + int dotIndex = fileName.lastIndexOf(QLatin1Char('.')); + if (dotIndex != -1) { + QString at2xfileName = fileName; + at2xfileName.insert(dotIndex, QStringLiteral("@2x")); + if (QFile::exists(at2xfileName)) + return at2xfileName; + } + return fileName; +} + static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format) { QPixmap pm; @@ -59,6 +74,8 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format) QString name = format.name(); if (name.startsWith(QLatin1String(":/"))) // auto-detect resources name.prepend(QLatin1String("qrc")); + QPaintDevice *pdev = doc->documentLayout()->paintDevice(); + name = resolve2xFile(name, pdev ? pdev->devicePixelRatio() : qApp->devicePixelRatio()); QUrl url = QUrl(name); const QVariant data = doc->resource(QTextDocument::ImageResource, url); if (data.type() == QVariant::Pixmap || data.type() == QVariant::Image) { @@ -85,6 +102,9 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format) doc->addResource(QTextDocument::ImageResource, url, pm); } + if (name.contains(QStringLiteral("@2x"))) + pm.setDevicePixelRatio(2.0); + return pm; } @@ -100,17 +120,20 @@ static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format) QSize size(width, height); if (!hasWidth || !hasHeight) { pm = getPixmap(doc, format); + const int pmWidth = pm.width() / pm.devicePixelRatio(); + const int pmHeight = pm.height() / pm.devicePixelRatio(); + if (!hasWidth) { if (!hasHeight) - size.setWidth(pm.width()); + size.setWidth(pmWidth); else - size.setWidth(qRound(height * (pm.width() / (qreal) pm.height()))); + size.setWidth(qRound(height * (pmWidth / (qreal) pmHeight))); } if (!hasHeight) { if (!hasWidth) - size.setHeight(pm.height()); + size.setHeight(pmHeight); else - size.setHeight(qRound(width * (pm.height() / (qreal) pm.width()))); + size.setHeight(qRound(width * (pmHeight / (qreal) pmWidth))); } } @@ -134,6 +157,8 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format) QString name = format.name(); if (name.startsWith(QLatin1String(":/"))) // auto-detect resources name.prepend(QLatin1String("qrc")); + QPaintDevice *pdev = doc->documentLayout()->paintDevice(); + name = resolve2xFile(name, pdev ? pdev->devicePixelRatio() : qApp->devicePixelRatio()); QUrl url = QUrl(name); const QVariant data = doc->resource(QTextDocument::ImageResource, url); if (data.type() == QVariant::Image) { @@ -159,6 +184,9 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format) doc->addResource(QTextDocument::ImageResource, url, image); } + if (name.contains(QStringLiteral("@2x"))) + image.setDevicePixelRatio(2.0); + return image; } @@ -175,9 +203,9 @@ static QSize getImageSize(QTextDocument *doc, const QTextImageFormat &format) if (!hasWidth || !hasHeight) { image = getImage(doc, format); if (!hasWidth) - size.setWidth(image.width()); + size.setWidth(image.width() / image.devicePixelRatio()); if (!hasHeight) - size.setHeight(image.height()); + size.setHeight(image.height() / image.devicePixelRatio()); } qreal scale = 1.0; -- cgit v1.2.3 From 000693018b50414b2cd46830b15073e5c8eefe2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 26 Feb 2014 12:33:29 +0100 Subject: Cocoa: Fix DnD when using native widgets. Adding a native widget such as QGLWidget often causes other widgets to become native, through native ancestor and sibling propagation. This includes QFocusFrame, which typically sits on top of item views. QFocusFrame is mostly transparent (except for the frame) and also has the WA_TransparentForMouseEvents flag set. Its window has the corresponding WindowTransparentForInput flag set. Cocoa does not know about WindowTransparentForInput. Forward the drag calls to the correct window. Task-number: QTBUG-37077 Change-Id: I02201c7027915b1e82d0cd7e9c2e787ca6b2338b Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index e17cd0a4cc..83a1f08973 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1648,6 +1648,21 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) } } +static QWindow *findEventTargetWindow(QWindow *candidate) +{ + while (candidate) { + if (!(candidate->flags() & Qt::WindowTransparentForInput)) + return candidate; + candidate = candidate->parent(); + } + return candidate; +} + +static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint point) +{ + return target->mapFromGlobal(source->mapToGlobal(point)); +} + - (NSDragOperation) draggingSourceOperationMaskForLocal:(BOOL)isLocal { Q_UNUSED(isLocal); @@ -1677,16 +1692,18 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) QPoint qt_windowPoint(windowPoint.x, windowPoint.y); Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]); + QWindow *target = findEventTargetWindow(m_window); + // update these so selecting move/copy/link works QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]]; QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect()); if ([sender draggingSource] != nil) { QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); - response = QWindowSystemInterface::handleDrag(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed); + response = QWindowSystemInterface::handleDrag(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); } else { QCocoaDropData mimeData([sender draggingPasteboard]); - response = QWindowSystemInterface::handleDrag(m_window, &mimeData, qt_windowPoint, qtAllowed); + response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); } return qt_mac_mapDropAction(response.acceptedAction()); @@ -1694,16 +1711,20 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) - (void)draggingExited:(id )sender { + QWindow *target = findEventTargetWindow(m_window); + NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil]; QPoint qt_windowPoint(windowPoint.x, windowPoint.y); // Send 0 mime data to indicate drag exit - QWindowSystemInterface::handleDrag(m_window, 0 ,qt_windowPoint, Qt::IgnoreAction); + QWindowSystemInterface::handleDrag(target, 0, mapWindowCoordinates(m_window, target, qt_windowPoint), Qt::IgnoreAction); } // called on drop, send the drop to Qt and return if it was accepted. - (BOOL)performDragOperation:(id )sender { + QWindow *target = findEventTargetWindow(m_window); + NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil]; QPoint qt_windowPoint(windowPoint.x, windowPoint.y); Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]); @@ -1711,10 +1732,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) QPlatformDropQtResponse response(false, Qt::IgnoreAction); if ([sender draggingSource] != nil) { QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); - response = QWindowSystemInterface::handleDrop(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed); + response = QWindowSystemInterface::handleDrop(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); } else { QCocoaDropData mimeData([sender draggingPasteboard]); - response = QWindowSystemInterface::handleDrop(m_window, &mimeData, qt_windowPoint, qtAllowed); + response = QWindowSystemInterface::handleDrop(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); } if (response.isAccepted()) { QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); @@ -1727,6 +1748,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) { Q_UNUSED(img); Q_UNUSED(operation); + QWindow *target = findEventTargetWindow(m_window); // keep our state, and QGuiApplication state (buttons member) in-sync, // or future mouse events will be processed incorrectly @@ -1739,7 +1761,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) NSPoint screenPoint = [window convertBaseToScreen :point]; QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y)); - QWindowSystemInterface::handleMouseEvent(m_window, qtWindowPoint, qtScreenPoint, m_buttons); + QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_window, target, qtWindowPoint), qtScreenPoint, m_buttons); } @end -- cgit v1.2.3 From 05cfb6cd09eb27f960362c077855959835dae88c Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 9 Apr 2014 14:19:32 +0200 Subject: HB-NG w/CoreText backend: Fix clustering of neutral characters Say you have a string with logical contents "abc ABC, " where lowercase is LTR and uppercase is RTL. In this case, the UBA will give "abc " LTR direction, and "ABC, " will get RTL. However, our itemization currently divides "ABC, " into two script items: "ABC" and ", ". CoreText will return glyphs in visual order, so for the first we will get "CBA" and for the second we will get ", ". But as the ", " item has an adapted directionality of RTL in the context of the full paragraph, it should actually be " ," visually. This caused a mismatch which broke the tst_QComplexText test with HB-NG using CoreText backend. As a temporary fix for this, we check whether the directionality of the first run in the text is different from the directionality expected by HB-NG. If this happens, it means the order of the glyphs produced by CoreText will be the reverse order of what is expected by HB-NG, and we therefore need to reverse it. Task-number: QTBUG-38113 Change-Id: I9f5a041791e4529a14041a362b2d5dd00490a38b Reviewed-by: Konstantin Ritt Reviewed-by: Simon Hausmann --- src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index 09f3171b30..4a905ee189 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -807,6 +807,9 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, buffer->clear_positions (); + bool bufferRtl = !HB_DIRECTION_IS_FORWARD (buffer->props.direction); + bool runRtl = (CTRunGetStatus(static_cast(CFArrayGetValueAtIndex(glyph_runs, 0))) & kCTRunStatusRightToLeft); + unsigned int count = buffer->len; for (unsigned int i = 0; i < count; ++i) { hb_glyph_info_t *info = &buffer->info[i]; @@ -816,6 +819,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, pos->x_advance = info->mask; pos->x_offset = info->var1.u32; pos->y_offset = info->var2.u32; + + if (bufferRtl != runRtl && i < count / 2) { + unsigned int temp = buffer->info[count - i - 1].cluster; + buffer->info[count - i - 1].cluster = info->cluster; + info->cluster = temp; + } } /* Fix up clusters so that we never return out-of-order indices; -- cgit v1.2.3 From 02ecd3ae40d8e10c56f5c92060257422a8ba9f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 13 Mar 2014 16:16:22 +0100 Subject: Make Xcode debug info format controllable through a qmake variable The default is still DWARF instead of DWARF with dSYM for static builds of Qt, so that debug builds of the final application don't take forever to build due to generating the dSYM file. Change-Id: I370d800d7c959e05c1a8780c4ebf58fff250daa1 Reviewed-by: Oswald Buddenhagen Reviewed-by: Fawzi Mohamed --- mkspecs/features/mac/default_post.prf | 7 +++++++ mkspecs/features/mac/default_pre.prf | 10 ++++++++++ mkspecs/macx-ios-clang/features/default_post.prf | 16 ---------------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index da3e22b5f3..530683552b 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -37,6 +37,13 @@ qt:!isEmpty(QT_CONFIG) { } } +macx-xcode:!isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) { + debug_information_format.name = DEBUG_INFORMATION_FORMAT + debug_information_format.value = $$QMAKE_XCODE_DEBUG_INFORMATION_FORMAT + debug_information_format.build = debug + QMAKE_MAC_XCODE_SETTINGS += debug_information_format +} + cache(QMAKE_XCODE_DEVELOPER_PATH, stash) cache(QMAKE_XCODE_VERSION, stash) diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf index c031403930..0cc8cd6dfd 100644 --- a/mkspecs/features/mac/default_pre.prf +++ b/mkspecs/features/mac/default_pre.prf @@ -33,6 +33,16 @@ isEmpty(QMAKE_TARGET_BUNDLE_PREFIX) { cache(QMAKE_TARGET_BUNDLE_PREFIX) } +# Make the default debug info format for static debug builds +# DWARF instead of DWARF with dSYM. This cuts down build times +# for application debug builds significantly, as Xcode doesn't +# have to pull out all the DWARF info from the Qt static libs +# and put it into a dSYM file. We don't need that dSYM file in +# the first place, since the information is available in the +# object files inside the archives (static libraries). +contains(QT_CONFIG, static): \ + QMAKE_XCODE_DEBUG_INFORMATION_FORMAT = dwarf + # This variable is used by the xcode_dynamic_library_suffix # feature, which allows Xcode to choose the Qt libraries to link to # at build time, depending on the current Xcode SDK and configuration. diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index 8b339dacdc..496553f8c0 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -178,22 +178,6 @@ macx-xcode { QMAKE_SUBSTITUTES += copy_image launch_images.files = $$copy_image.output QMAKE_BUNDLE_DATA += launch_images - - # Make the default debug information format for debug builds - # DWARF instead of DWARF with dSYM. This cuts down build times - # for application debug builds significantly, as Xcode doesn't - # have to pull out all the DWARF info from our static libraries - # and put it into a dSYM file. We don't need that dSYM file in - # the first place, since the information is available in the - # object files inside the archives (static libraries). The only - # unfortunate side effect of this is that the user won't be - # able to break on specific lines of main(). This is due to - # using ld to rename the main-function, and will go away once - # we implement a separate tool to do the symbol renaming. - debug_information_format.name = DEBUG_INFORMATION_FORMAT - debug_information_format.value = dwarf - debug_information_format.build = debug - QMAKE_MAC_XCODE_SETTINGS += debug_information_format } macx-xcode { -- cgit v1.2.3 From b1afb91ffe7727ec59e4baf0124d16e03b1d5539 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Tue, 8 Apr 2014 23:12:28 +0200 Subject: XCB: Print error code on Xlib I/O errors When Xlib detects that its underlying XCB connection got into an error state, it calls its I/O error handler. However, the default implementation doesn't print the error code from XCB which might be useful for debugging. This commit adds an I/O error handler which prints the error code from XCB with a string describing the error and then calls Xlib's default error handler. Change-Id: I7f1fb3f1e8d0fdc3ac9db03ae7d154330c31db0c Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 66b8401ea2..f5f6c712c5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -93,10 +93,37 @@ QT_BEGIN_NAMESPACE #ifdef XCB_USE_XLIB +static const char * const xcbConnectionErrors[] = { + "No error", /* Error 0 */ + "I/O error", /* XCB_CONN_ERROR */ + "Unsupported extension used", /* XCB_CONN_CLOSED_EXT_NOTSUPPORTED */ + "Out of memory", /* XCB_CONN_CLOSED_MEM_INSUFFICIENT */ + "Maximum allowed requested length exceeded", /* XCB_CONN_CLOSED_REQ_LEN_EXCEED */ + "Failed to parse display string", /* XCB_CONN_CLOSED_PARSE_ERR */ + "No such screen on display", /* XCB_CONN_CLOSED_INVALID_SCREEN */ + "Error during FD passing" /* XCB_CONN_CLOSED_FDPASSING_FAILED */ +}; + static int nullErrorHandler(Display *, XErrorEvent *) { return 0; } + +static int ioErrorHandler(Display *dpy) +{ + xcb_connection_t *conn = XGetXCBConnection(dpy); + if (conn != NULL) { + /* Print a message with a textual description of the error */ + int code = xcb_connection_has_error(conn); + const char *str = "Unknown error"; + int arrayLength = sizeof(xcbConnectionErrors) / sizeof(xcbConnectionErrors[0]); + if (code >= 0 && code < arrayLength) + str = xcbConnectionErrors[code]; + + qWarning("The X11 connection broke: %s (code %d)", str, code); + } + return _XDefaultIOError(dpy); +} #endif QXcbScreen* QXcbConnection::findOrCreateScreen(QList& newScreens, @@ -284,6 +311,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra m_connection = XGetXCBConnection(dpy); XSetEventQueueOwner(dpy, XCBOwnsEventQueue); XSetErrorHandler(nullErrorHandler); + XSetIOErrorHandler(ioErrorHandler); m_xlib_display = dpy; } #else -- cgit v1.2.3 From 78af72590760ea4853fa79370cd7c017ad1760f7 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 9 Apr 2014 16:24:06 +0200 Subject: Cocoa: Set the COCOA_MENU_ANCESTOR() also when sync'ing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-38044 Change-Id: I2769bf2f4beec058c15ba1d126e59106f41dab37 Reviewed-by: Morten Johan Sørvig Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoamenu.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 35e8fdebb4..6acc062eb9 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -269,7 +269,6 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem * QCocoaMenuItem *cocoaItem = static_cast(menuItem); QCocoaMenuItem *beforeItem = static_cast(before); - SET_COCOA_MENU_ANCESTOR(menuItem, this); cocoaItem->sync(); if (beforeItem) { int index = m_menuItems.indexOf(beforeItem); @@ -315,6 +314,7 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) } else { [m_nativeMenu addItem: item->nsItem()]; } + SET_COCOA_MENU_ANCESTOR(item, this); } void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem) -- cgit v1.2.3 From bab494e4d046f5617d19f5fec35eeff94377c51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 9 Apr 2014 12:16:09 +0200 Subject: Cocoa: Send expose event on screen change. Required to repaint OpenGL content properly. Task-number: QTBUG-38105 Change-Id: Ie9441d56bd9d1a4eb399210369592f03e19c4929 Reviewed-by: Gabriel de Dietrich Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoawindow.h | 1 + src/plugins/platforms/cocoa/qcocoawindow.mm | 4 +++- src/plugins/platforms/cocoa/qnsview.mm | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 7a01835d5b..bb5c0c1974 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -272,6 +272,7 @@ public: // for QNSView bool m_geometryUpdateExposeAllowed; bool m_isExposed; QRect m_exposedGeometry; + qreal m_exposedDevicePixelRatio; int m_registerTouchCount; bool m_resizableTransientParent; bool m_hiddenByClipping; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5a4ac9b2cc..5def64ee0a 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1710,6 +1710,7 @@ void QCocoaWindow::exposeWindow() if (!m_isExposed) { m_isExposed = true; m_exposedGeometry = geometry(); + m_exposedDevicePixelRatio = devicePixelRatio(); QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); } } @@ -1735,11 +1736,12 @@ void QCocoaWindow::updateExposedGeometry() if (!isWindowExposable()) return; - if (m_exposedGeometry == geometry()) + if (m_exposedGeometry == geometry() && m_exposedDevicePixelRatio == devicePixelRatio()) return; m_isExposed = true; m_exposedGeometry = geometry(); + m_exposedDevicePixelRatio = devicePixelRatio(); QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 83a1f08973..0b9683a3ef 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -329,6 +329,7 @@ static QTouchDevice *touchDevice = 0; if (m_window) { NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen]; if (screenIndex != NSNotFound) { + m_platformWindow->updateExposedGeometry(); QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex); QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen()); } -- cgit v1.2.3