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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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 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 +++ 2 files changed, 8 insertions(+) (limited to 'src') 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 { -- 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') 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()); -- 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 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(-) (limited to 'src') 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 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 --- 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 - 45 files changed, 1788 insertions(+), 1983 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 (limited to 'src') 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(-) (limited to 'src') 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 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 --- src/corelib/io/qfilesystemengine_win.cpp | 4 ++-- src/corelib/kernel/qeventdispatcher_win.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') 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; } -- 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(-) (limited to 'src') 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 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(-) (limited to 'src') 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 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(+) (limited to 'src') 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 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(-) (limited to 'src') 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(+) (limited to 'src') 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 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(-) (limited to 'src') 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(-) (limited to 'src') 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 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(+) (limited to 'src') 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 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(-) (limited to 'src') 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(-) (limited to 'src') 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 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'src') 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); } } -- 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(+) (limited to 'src') 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 ++++- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src') 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) { -- 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 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') 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 -- 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 --- 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 ++-- 10 files changed, 20 insertions(+), 77 deletions(-) (limited to 'src') 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 } -- 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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 -- 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(+) (limited to 'src') 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(+) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 --- src/corelib/global/qlogging.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 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 + 3 files changed, 30 insertions(+) (limited to 'src') 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); -- 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(-) (limited to 'src') 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 +++++- 7 files changed, 102 insertions(+), 3 deletions(-) (limited to 'src') 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; +} -- 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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 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 +++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src') 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 -- 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(-) (limited to 'src') 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(-) (limited to 'src') 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 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 ++ 2 files changed, 10 insertions(+) (limited to 'src') 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); -- 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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 ++ 2 files changed, 16 insertions(+) (limited to 'src') 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); -- 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(-) (limited to 'src') 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(-) (limited to 'src') 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 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(-) (limited to 'src') 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 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(+) (limited to 'src') 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(-) (limited to 'src') 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 +- 10 files changed, 226 insertions(+), 62 deletions(-) create mode 100644 src/gui/accessible/qaccessiblecache_mac.mm (limited to 'src') 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: -- 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(+) (limited to 'src') 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 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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(-) (limited to 'src') 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 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(+) (limited to 'src') 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 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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 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(-) (limited to 'src') 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(-) (limited to 'src') 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 +++++ 3 files changed, 80 insertions(+) (limited to 'src') 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 -- 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(-) (limited to 'src') 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 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 --- src/plugins/accessible/widgets/widgets.pro | 1 + 1 file changed, 1 insertion(+) (limited to 'src') 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 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 --- 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 + src/plugins/platforminputcontexts/compose/compose.pro | 1 + src/plugins/platforminputcontexts/ibus/ibus.pro | 1 + src/plugins/platformthemes/gtk2/gtk2.pro | 1 + src/printsupport/printsupport.pro | 3 +++ 11 files changed, 16 insertions(+) (limited to 'src') 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 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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(+) (limited to 'src') 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 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(+) (limited to 'src') 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(-) (limited to 'src') 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(-) (limited to 'src') 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