summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-03-28 12:33:32 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-03-28 12:33:32 +0100
commitad809526d63b2c6a1dd94282fa0a807f72ee580d (patch)
tree05501efa0dae0b4b8cf72d254efbbbab2ad3cb2d /src/plugins
parent9149f31aeaf3fce0c5ba5c20da0b9f2b56368abb (diff)
parentc7cca2dd74bcfb0a2020fbb537fd47b50b2775c0 (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: src/plugins/platforms/qnx/qqnxtheme.cpp src/widgets/dialogs/qfileinfogatherer.cpp src/widgets/dialogs/qfilesystemmodel.cpp Change-Id: Ifa536969c4beafcdfeebbf6beda1674b86750be8
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/accessible/widgets/itemviews.cpp7
-rw-r--r--src/plugins/accessible/widgets/itemviews.h1
-rw-r--r--src/plugins/accessible/widgets/main.cpp13
-rw-r--r--src/plugins/accessible/widgets/widgets.json6
-rw-r--r--src/plugins/generic/generic.pro4
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.json3
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.pro20
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp402
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h128
-rw-r--r--src/plugins/platforminputcontexts/compose/main.cpp70
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp268
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h85
-rw-r--r--src/plugins/platforminputcontexts/compose/xkbcommon_workaround.h105
-rw-r--r--src/plugins/platforminputcontexts/platforminputcontexts.pro6
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.cpp27
-rw-r--r--src/plugins/platforms/android/src/qandroidinputcontext.cpp9
-rw-r--r--src/plugins/platforms/android/src/qandroidinputcontext.h2
-rw-r--r--src/plugins/platforms/android/src/src.pri2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm27
-rw-r--r--src/plugins/platforms/cocoa/qcocoakeymapper.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h16
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm32
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h12
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm96
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h5
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm131
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractnavigator.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxbuffer.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxclipboard.cpp4
-rw-r--r--src/plugins/platforms/qnx/qqnxclipboard.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxcursor.cpp4
-rw-r--r--src/plugins/platforms/qnx/qqnxcursor.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp4
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatorpps.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxrootwindow.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxtheme.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h6
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp12
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h8
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp5
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp6
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp11
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h1
68 files changed, 1501 insertions, 149 deletions
diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp
index cb34116f32..822d9d8c77 100644
--- a/src/plugins/accessible/widgets/itemviews.cpp
+++ b/src/plugins/accessible/widgets/itemviews.cpp
@@ -47,7 +47,7 @@
#include <qtreeview.h>
#include <private/qtreewidget_p.h>
#include <QtGui/private/qaccessible2_p.h>
-#include <QDebug>
+#include <QtWidgets/private/qwidget_p.h>
#ifndef QT_NO_ACCESSIBILITY
@@ -136,6 +136,11 @@ QAccessibleTable::QAccessibleTable(QWidget *w)
}
}
+bool QAccessibleTable::isValid() const
+{
+ return (view() && !qobject_cast<QWidget*>(view())->d_func()->data.in_destructor);
+}
+
QAccessibleTable::~QAccessibleTable()
{
}
diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h
index bba698bda2..af885fe6c1 100644
--- a/src/plugins/accessible/widgets/itemviews.h
+++ b/src/plugins/accessible/widgets/itemviews.h
@@ -63,6 +63,7 @@ class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleObje
{
public:
explicit QAccessibleTable(QWidget *w);
+ bool isValid() const;
virtual ~QAccessibleTable();
diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp
index 92cda9f3ca..ade4979256 100644
--- a/src/plugins/accessible/widgets/main.cpp
+++ b/src/plugins/accessible/widgets/main.cpp
@@ -172,12 +172,11 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec
iface = new QAccessibleMenu(widget);
#endif
#ifndef QT_NO_ITEMVIEWS
- } else if (classname == QLatin1String("QAbstractItemView")) {
- if (qobject_cast<const QTreeView*>(widget)) {
- iface = new QAccessibleTree(widget);
- } else {
- iface = new QAccessibleTable(widget);
- }
+ } else if (classname == QLatin1String("QTreeView")) {
+ iface = new QAccessibleTree(widget);
+ } else if (classname == QLatin1String("QTableView") || classname == QLatin1String("QListView")) {
+ iface = new QAccessibleTable(widget);
+ // ### This should be cleaned up. We return the parent for the scrollarea to hide it.
} else if (classname == QLatin1String("QWidget")
&& widget->objectName() == QLatin1String("qt_scrollarea_viewport")
&& qobject_cast<QAbstractItemView*>(widget->parentWidget())) {
@@ -254,7 +253,7 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec
} else if (classname == QLatin1String("QDesktopScreenWidget")) {
iface = 0;
- } else {
+ } else if (classname == QLatin1String("QWidget")) {
iface = new QAccessibleWidget(widget);
}
diff --git a/src/plugins/accessible/widgets/widgets.json b/src/plugins/accessible/widgets/widgets.json
index 094987daf5..3969fcd527 100644
--- a/src/plugins/accessible/widgets/widgets.json
+++ b/src/plugins/accessible/widgets/widgets.json
@@ -24,11 +24,12 @@
"QPlainTextEdit",
"QMenuBar",
"QMenu",
- "QHeaderView",
"QTabBar",
"QToolBar",
"QSizeGrip",
- "QAbstractItemView",
+ "QListView",
+ "QTreeView",
+ "QTableView",
"QWidget",
"QSplitter",
"QSplitterHandle",
@@ -47,7 +48,6 @@
"QScrollArea",
"QCalendarWidget",
"QDockWidget",
- "QAccessibleWidget",
"QDesktopScreenWidget"
]
}
diff --git a/src/plugins/generic/generic.pro b/src/plugins/generic/generic.pro
index 078db2f477..18a8295d3c 100644
--- a/src/plugins/generic/generic.pro
+++ b/src/plugins/generic/generic.pro
@@ -5,3 +5,7 @@ TEMPLATE = subdirs
contains(QT_CONFIG, evdev) {
SUBDIRS += evdevmouse evdevtouch evdevkeyboard evdevtablet
}
+
+contains(QT_CONFIG, tslib) {
+ SUBDIRS += tslib
+}
diff --git a/src/plugins/platforminputcontexts/compose/compose.json b/src/plugins/platforminputcontexts/compose/compose.json
new file mode 100644
index 0000000000..2daf89ed30
--- /dev/null
+++ b/src/plugins/platforminputcontexts/compose/compose.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "compose" ]
+}
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
new file mode 100644
index 0000000000..6387a47a4c
--- /dev/null
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -0,0 +1,20 @@
+TARGET = composeplatforminputcontextplugin
+
+PLUGIN_TYPE = platforminputcontexts
+PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin
+load(qt_plugin)
+
+QT += gui-private
+
+LIBS += $$QMAKE_LIBS_XKBCOMMON
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
+
+SOURCES += $$PWD/main.cpp \
+ $$PWD/qcomposeplatforminputcontext.cpp \
+ $$PWD/generator/qtablegenerator.cpp \
+
+HEADERS += $$PWD/qcomposeplatforminputcontext.h \
+ $$PWD/generator/qtablegenerator.h \
+ $$PWD/xkbcommon_workaround.h \
+
+OTHER_FILES += $$PWD/compose.json
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
new file mode 100644
index 0000000000..5941936aec
--- /dev/null
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -0,0 +1,402 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtablegenerator.h"
+
+#include <QtCore/QRegularExpression>
+#include <QtCore/QByteArray>
+#include <QtCore/QTextCodec>
+#include <QtCore/QDebug>
+#include <QtCore/QStringList>
+#include <QtCore/QString>
+
+#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon_workaround.h>
+
+#include <X11/keysym.h>
+
+//#define DEBUG_GENERATOR
+
+TableGenerator::TableGenerator() : m_state(NoErrors),
+ m_systemComposeDir(QString())
+{
+ initPossibleLocations();
+ findComposeFile();
+ orderComposeTable();
+#ifdef DEBUG_GENERATOR
+ printComposeTable();
+#endif
+}
+
+void TableGenerator::initPossibleLocations()
+{
+ // AFAICT there is no way to know the exact location
+ // of the compose files. It depends on how Xlib was configured
+ // on a specific platform. During the "./configure" process
+ // xlib generates a config.h file which contains a bunch of defines,
+ // including XLOCALEDIR which points to the location of the compose file dir.
+ // To add an extra system path use the QTCOMPOSE environment variable
+ if (qEnvironmentVariableIsSet("QTCOMPOSE")) {
+ m_possibleLocations.append(QString(qgetenv("QTCOMPOSE")));
+ }
+ m_possibleLocations.append(QStringLiteral("/usr/share/X11/locale"));
+ m_possibleLocations.append(QStringLiteral("/usr/lib/X11/locale"));
+}
+
+void TableGenerator::findComposeFile()
+{
+ bool found = false;
+ // check if XCOMPOSEFILE points to a Compose file
+ if (qEnvironmentVariableIsSet("XCOMPOSEFILE")) {
+ QString composeFile(qgetenv("XCOMPOSEFILE"));
+ if (composeFile.endsWith(QLatin1String("Compose")))
+ found = processFile(composeFile);
+ else
+ qWarning("Qt Warning: XCOMPOSEFILE doesn't point to a valid Compose file");
+#ifdef DEBUG_GENERATOR
+ if (found)
+ qDebug() << "Using Compose file from: " << composeFile;
+#endif
+ }
+
+ // check if user’s home directory has a file named .XCompose
+ if (!found && cleanState()) {
+ QString composeFile = qgetenv("HOME") + QStringLiteral("/.XCompose");
+ if (QFile(composeFile).exists())
+ found = processFile(composeFile);
+#ifdef DEBUG_GENERATOR
+ if (found)
+ qDebug() << "Using Compose file from: " << composeFile;
+#endif
+ }
+
+ // check for the system provided compose files
+ if (!found && cleanState()) {
+ readLocaleMappings();
+
+ if (cleanState()) {
+
+ QString table = m_localeToTable.value(locale().toUpper());
+ if (table.isEmpty())
+ // no table mappings for the system's locale in the compose.dir
+ m_state = UnsupportedLocale;
+ else
+ found = processFile(systemComposeDir() + QLatin1String("/") + table);
+#ifdef DEBUG_GENERATOR
+ if (found)
+ qDebug() << "Using Compose file from: " <<
+ systemComposeDir() + QLatin1String("/") + table;
+#endif
+ }
+ }
+
+ if (found && m_composeTable.isEmpty())
+ m_state = EmptyTable;
+
+ if (!found)
+ m_state = MissingComposeFile;
+}
+
+bool TableGenerator::findSystemComposeDir()
+{
+ bool found = false;
+ for (int i = 0; i < m_possibleLocations.size(); ++i) {
+ QString path = m_possibleLocations.at(i);
+ if (QFile(path + QLatin1String("/compose.dir")).exists()) {
+ m_systemComposeDir = path;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ // should we ask to report this in the qt bug tracker?
+ m_state = UnknownSystemComposeDir;
+ qWarning("Qt Warning: Could not find a location of the system's Compose files. "
+ "Consider setting the QTCOMPOSE environment variable.");
+ }
+
+ return found;
+}
+
+QString TableGenerator::systemComposeDir()
+{
+ if (m_systemComposeDir.isNull()
+ && !findSystemComposeDir()) {
+ return QLatin1String("$QTCOMPOSE");
+ }
+
+ return m_systemComposeDir;
+}
+
+QString TableGenerator::locale() const
+{
+ char *name = setlocale(LC_CTYPE, (char *)0);
+ return QLatin1String(name);
+}
+
+void TableGenerator::readLocaleMappings()
+{
+ QFile mappings(systemComposeDir() + QLatin1String("/compose.dir"));
+ if (mappings.exists()) {
+ mappings.open(QIODevice::ReadOnly);
+ QTextStream in(&mappings);
+ // formating of compose.dir has some inconsistencies
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ if (!line.startsWith("#") && line.size() != 0 &&
+ line.at(0).isLower()) {
+
+ QStringList pair = line.split(QRegExp(QLatin1String("\\s+")));
+ QString table = pair.at(0);
+ if (table.endsWith(QLatin1String(":")))
+ table.remove(table.size() - 1, 1);
+
+ m_localeToTable.insert(pair.at(1).toUpper(), table);
+ }
+ }
+ mappings.close();
+ }
+}
+
+bool TableGenerator::processFile(QString composeFileName)
+{
+ QFile composeFile(composeFileName);
+ if (composeFile.exists()) {
+ composeFile.open(QIODevice::ReadOnly);
+ parseComposeFile(&composeFile);
+ return true;
+ }
+ qWarning() << QString(QLatin1String("Qt Warning: Compose file: \"%1\" can't be found"))
+ .arg(composeFile.fileName());
+ return false;
+}
+
+TableGenerator::~TableGenerator()
+{
+}
+
+QList<QComposeTableElement> TableGenerator::composeTable() const
+{
+ return m_composeTable;
+}
+
+void TableGenerator::parseComposeFile(QFile *composeFile)
+{
+#ifdef DEBUG_GENERATOR
+ qDebug() << "TableGenerator::parseComposeFile: " << composeFile->fileName();
+#endif
+ QTextStream in(composeFile);
+
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ if (line.startsWith(QLatin1String("<"))) {
+ parseKeySequence(line);
+ } else if (line.startsWith(QLatin1String("include"))) {
+ parseIncludeInstruction(line);
+ }
+ }
+
+ composeFile->close();
+}
+
+void TableGenerator::parseIncludeInstruction(QString line)
+{
+ // Parse something that looks like:
+ // include "/usr/share/X11/locale/en_US.UTF-8/Compose"
+ QString quote = QStringLiteral("\"");
+ line.remove(0, line.indexOf(quote) + 1);
+ line.chop(line.length() - line.indexOf(quote));
+
+ // expand substitutions if present
+ line.replace(QLatin1String("%H"), QString(qgetenv("HOME")));
+ line.replace(QLatin1String("%L"), locale());
+ line.replace(QLatin1String("%S"), systemComposeDir());
+
+ processFile(line);
+}
+
+ushort TableGenerator::keysymToUtf8(uint32_t sym)
+{
+ QByteArray chars;
+ int bytes;
+ chars.resize(8);
+
+ if (needWorkaround(sym)) {
+ uint32_t codepoint;
+ if (sym == XKB_KEY_KP_Space)
+ codepoint = XKB_KEY_space & 0x7f;
+ else
+ codepoint = sym & 0x7f;
+
+ bytes = utf32_to_utf8(codepoint, chars.data());
+ } else {
+ bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
+ }
+
+ if (bytes == -1)
+ qWarning("TableGenerator::keysymToUtf8 - buffer too small");
+
+ chars.resize(bytes-1);
+
+#ifdef DEBUG_GENERATOR
+ QTextCodec *codec = QTextCodec::codecForLocale();
+ qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16))
+ .arg(codec->toUnicode(chars));
+#endif
+ const QChar *ch = QString(chars.data()).unicode();
+ return ch->unicode();
+}
+
+uint32_t TableGenerator::stringToKeysym(QString keysymName)
+{
+ uint32_t keysym;
+ const char *name = keysymName.toLatin1().constData();
+
+ if ((keysym = xkb_keysym_from_name(name, (xkb_keysym_flags)0)) == XKB_KEY_NoSymbol)
+ qWarning() << QString("Qt Warrning - invalid keysym: %1").arg(keysymName);
+
+ return keysym;
+}
+
+void TableGenerator::parseKeySequence(QString line)
+{
+ // we are interested in the lines with the following format:
+ // <Multi_key> <numbersign> <S> : "♬" U266c # BEAMED SIXTEENTH NOTE
+ int keysEnd = line.indexOf(QLatin1String(":"));
+ QString keys = line.left(keysEnd).trimmed();
+
+ // find the key sequence
+ QString regexp = QStringLiteral("<[^>]+>");
+ QRegularExpression reg(regexp);
+ QRegularExpressionMatchIterator i = reg.globalMatch(keys);
+ QStringList keyList;
+ while (i.hasNext()) {
+ QRegularExpressionMatch match = i.next();
+ QString word = match.captured(0);
+ keyList << word;
+ }
+
+ QComposeTableElement elem;
+ QString quote = QStringLiteral("\"");
+ // find the composed value - strings may be direct text encoded in the locale
+ // for which the compose file is to be used, or an escaped octal or hexadecimal
+ // character code. Octal codes are specified as "\123" and hexadecimal codes as "\0x123a".
+ int composeValueIndex = line.indexOf(quote, keysEnd) + 1;
+ const QChar valueType(line.at(composeValueIndex));
+
+ if (valueType == '\\' && line.at(composeValueIndex + 1).isDigit()) {
+ // handle octal and hex code values
+ QChar detectBase(line.at(composeValueIndex + 2));
+ QString codeValue = line.mid(composeValueIndex + 1, line.lastIndexOf(quote) - composeValueIndex - 1);
+ if (detectBase == 'x') {
+ // hexadecimal character code
+ elem.value = keysymToUtf8(codeValue.toUInt(0, 16));
+ } else {
+ // octal character code
+ QString hexStr = QString::number(codeValue.toUInt(0, 8), 16);
+ elem.value = keysymToUtf8(hexStr.toUInt(0, 16));
+ }
+ } else {
+ // handle direct text encoded in the locale
+ elem.value = valueType.unicode();
+ }
+
+ // find the comment
+ int commnetIndex = line.lastIndexOf(quote) + 1;
+ elem.comment = line.mid(commnetIndex).trimmed();
+
+ // Convert to X11 keysym
+ int count = keyList.length();
+ for (int i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) {
+ if (i < count) {
+ QString keysym = keyList.at(i);
+ keysym.remove(keysym.length() - 1, 1);
+ keysym.remove(0, 1);
+
+ if (keysym == QLatin1String("dead_inverted_breve"))
+ keysym = QStringLiteral("dead_invertedbreve");
+ else if (keysym == QLatin1String("dead_double_grave"))
+ keysym = QStringLiteral("dead_doublegrave");
+
+ elem.keys[i] = stringToKeysym(keysym);
+ } else {
+ elem.keys[i] = 0;
+ }
+ }
+ m_composeTable.append(elem);
+}
+
+void TableGenerator::printComposeTable() const
+{
+ if (composeTable().isEmpty())
+ return;
+
+ QString output;
+ QComposeTableElement elem;
+ QString comma = QStringLiteral(",");
+ int tableSize = m_composeTable.size();
+ for (int i = 0; i < tableSize; ++i) {
+ elem = m_composeTable.at(i);
+ output.append(QLatin1String("{ {"));
+ for (int j = 0; j < QT_KEYSEQUENCE_MAX_LEN; j++) {
+ output.append(QString(QLatin1String("0x%1, ")).arg(QString::number(elem.keys[j],16)));
+ }
+ // take care of the trailing comma
+ if (i == tableSize - 1)
+ comma = QStringLiteral("");
+ output.append(QString(QLatin1String("}, 0x%1, \"\" }%2 // %3 \n"))
+ .arg(QString::number(elem.value,16))
+ .arg(comma)
+ .arg(elem.comment));
+ }
+
+ qDebug() << "output: \n" << output;
+}
+
+void TableGenerator::orderComposeTable()
+{
+ // Stable-sorting to ensure that the item that appeared before the other in the
+ // original container will still appear first after the sort. This property is
+ // needed to handle the cases when user re-defines already defined key sequence
+ qStableSort(m_composeTable.begin(), m_composeTable.end(), Compare());
+}
+
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
new file mode 100644
index 0000000000..11e7b2b422
--- /dev/null
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTABLEGENERATOR_H
+#define QTABLEGENERATOR_H
+
+#include <QtCore/QList>
+#include <QtCore/QFile>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+
+#define QT_KEYSEQUENCE_MAX_LEN 6
+
+struct QComposeTableElement {
+ uint keys[QT_KEYSEQUENCE_MAX_LEN];
+ uint value;
+ QString comment;
+};
+
+class Compare
+{
+public:
+ bool operator () (const QComposeTableElement &lhs, const uint rhs[QT_KEYSEQUENCE_MAX_LEN])
+ {
+ for (size_t i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) {
+ if (lhs.keys[i] != rhs[i])
+ return (lhs.keys[i] < rhs[i]);
+ }
+ return false;
+ }
+
+ bool operator () (const QComposeTableElement &lhs, const QComposeTableElement &rhs)
+ {
+ for (size_t i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) {
+ if (lhs.keys[i] != rhs.keys[i])
+ return (lhs.keys[i] < rhs.keys[i]);
+ }
+ return false;
+ }
+};
+
+class TableGenerator
+{
+
+public:
+ enum TableState
+ {
+ UnsupportedLocale,
+ EmptyTable,
+ UnknownSystemComposeDir,
+ MissingComposeFile,
+ NoErrors
+ };
+
+ TableGenerator();
+ ~TableGenerator();
+
+ void parseComposeFile(QFile *composeFile);
+ void printComposeTable() const;
+ void orderComposeTable();
+
+ QList<QComposeTableElement> composeTable() const;
+ TableState tableState() const { return m_state; }
+
+protected:
+ bool processFile(QString composeFileName);
+ void parseKeySequence(QString line);
+ void parseIncludeInstruction(QString line);
+
+ void findComposeFile();
+ bool findSystemComposeDir();
+ QString systemComposeDir();
+
+ ushort keysymToUtf8(uint32_t sym);
+ uint32_t stringToKeysym(QString keysymName);
+
+ void readLocaleMappings();
+ void initPossibleLocations();
+ bool cleanState() const { return ((m_state & NoErrors) == NoErrors); }
+ QString locale() const;
+
+private:
+ QList<QComposeTableElement> m_composeTable;
+ QMap<QString, QString> m_localeToTable;
+ TableState m_state;
+ QString m_systemComposeDir;
+ QList<QString> m_possibleLocations;
+};
+
+#endif // QTABLEGENERATOR_H
diff --git a/src/plugins/platforminputcontexts/compose/main.cpp b/src/plugins/platforminputcontexts/compose/main.cpp
new file mode 100644
index 0000000000..728c60caf5
--- /dev/null
+++ b/src/plugins/platforminputcontexts/compose/main.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpa/qplatforminputcontextplugin_p.h>
+
+#include <QtCore/QStringList>
+
+#include "qcomposeplatforminputcontext.h"
+
+QT_BEGIN_NAMESPACE
+
+class QComposePlatformInputContextPlugin : public QPlatformInputContextPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface" FILE "compose.json")
+
+public:
+ QComposeInputContext *create(const QString &, const QStringList &);
+};
+
+QComposeInputContext *QComposePlatformInputContextPlugin::create(const QString &system, const QStringList &paramList)
+{
+ Q_UNUSED(paramList);
+
+ if (system.compare(system, QStringLiteral("compose"), Qt::CaseInsensitive) == 0)
+ return new QComposeInputContext;
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
new file mode 100644
index 0000000000..433c9eec37
--- /dev/null
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcomposeplatforminputcontext.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtGui/QKeyEvent>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+//#define DEBUG_COMPOSING
+
+static const int ignoreKeys[] = {
+ Qt::Key_Shift,
+ Qt::Key_Control,
+ Qt::Key_Meta,
+ Qt::Key_Alt,
+ Qt::Key_CapsLock,
+ Qt::Key_Super_L,
+ Qt::Key_Super_R,
+ Qt::Key_Hyper_L,
+ Qt::Key_Hyper_R,
+ Qt::Key_Mode_switch
+};
+
+static const int composingKeys[] = {
+ Qt::Key_Multi_key,
+ Qt::Key_Dead_Grave,
+ Qt::Key_Dead_Acute,
+ Qt::Key_Dead_Circumflex,
+ Qt::Key_Dead_Tilde,
+ Qt::Key_Dead_Macron,
+ Qt::Key_Dead_Breve,
+ Qt::Key_Dead_Abovedot,
+ Qt::Key_Dead_Diaeresis,
+ Qt::Key_Dead_Abovering,
+ Qt::Key_Dead_Doubleacute,
+ Qt::Key_Dead_Caron,
+ Qt::Key_Dead_Cedilla,
+ Qt::Key_Dead_Ogonek,
+ Qt::Key_Dead_Iota,
+ Qt::Key_Dead_Voiced_Sound,
+ Qt::Key_Dead_Semivoiced_Sound,
+ Qt::Key_Dead_Belowdot,
+ Qt::Key_Dead_Hook,
+ Qt::Key_Dead_Horn
+};
+
+QComposeInputContext::QComposeInputContext()
+{
+ TableGenerator reader;
+ m_tableState = reader.tableState();
+
+ if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) {
+ m_composeTable = reader.composeTable();
+ clearComposeBuffer();
+ }
+}
+
+bool QComposeInputContext::filterEvent(const QEvent *event)
+{
+ // if there were errors when generating the compose table input
+ // context should not try to filter anything, simply return false
+ if ((m_tableState & TableGenerator::NoErrors) != TableGenerator::NoErrors)
+ return false;
+
+ QKeyEvent *keyEvent = (QKeyEvent *)event;
+ // should pass only the key presses
+ if (keyEvent->type() != QEvent::KeyPress) {
+ return false;
+ }
+
+ int keyval = keyEvent->key();
+ int keysym = 0;
+
+ if (ignoreKey(keyval))
+ return false;
+
+ QString text = keyEvent->text();
+ if (!composeKey(keyval) && text.isEmpty())
+ return false;
+
+ keysym = keyEvent->nativeVirtualKey();
+
+ int nCompose = 0;
+ while (m_composeBuffer[nCompose] != 0 && nCompose < QT_KEYSEQUENCE_MAX_LEN)
+ nCompose++;
+
+ if (nCompose == QT_KEYSEQUENCE_MAX_LEN) {
+ reset();
+ nCompose = 0;
+ }
+
+ m_composeBuffer[nCompose] = keysym;
+ // check sequence
+ if (checkComposeTable())
+ return true;
+
+ return false;
+}
+
+bool QComposeInputContext::isValid() const
+{
+ return true;
+}
+
+void QComposeInputContext::setFocusObject(QObject *object)
+{
+ m_focusObject = object;
+}
+
+void QComposeInputContext::reset()
+{
+ clearComposeBuffer();
+}
+
+void QComposeInputContext::update(Qt::InputMethodQueries q)
+{
+ QPlatformInputContext::update(q);
+}
+
+static bool isDuplicate(const QComposeTableElement &lhs, const QComposeTableElement &rhs)
+{
+ for (size_t i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) {
+ if (lhs.keys[i] != rhs.keys[i])
+ return false;
+ }
+ return true;
+}
+
+bool QComposeInputContext::checkComposeTable()
+{
+ QList<QComposeTableElement>::iterator it =
+ qLowerBound(m_composeTable.begin(), m_composeTable.end(), m_composeBuffer, Compare());
+
+ // prevent dereferencing an 'end' iterator, which would result in a crash
+ if (it == m_composeTable.end())
+ it -= 1;
+
+ QComposeTableElement elem = *it;
+ // would be nicer if qLowerBound had API that tells if the item was actually found
+ if (m_composeBuffer[0] != elem.keys[0]) {
+#ifdef DEBUG_COMPOSING
+ qDebug( "### no match ###" );
+#endif
+ reset();
+ return false;
+ }
+ // check if compose buffer is matched
+ for (int i=0; i < QT_KEYSEQUENCE_MAX_LEN; i++) {
+
+ // check if partial match
+ if (m_composeBuffer[i] == 0 && elem.keys[i]) {
+#ifdef DEBUG_COMPOSING
+ qDebug("### partial match ###");
+#endif
+ return true;
+ }
+
+ if (m_composeBuffer[i] != elem.keys[i]) {
+#ifdef DEBUG_COMPOSING
+ qDebug("### different entry ###");
+#endif
+ reset();
+ return i != 0;
+ }
+ }
+#ifdef DEBUG_COMPOSING
+ qDebug("### match exactly ###");
+#endif
+
+ // check if the key sequence is overwriten - see the comment in
+ // TableGenerator::orderComposeTable()
+ int next = 1;
+ do {
+ // if we are at the end of the table, then we have nothing to do here
+ if (it + next != m_composeTable.end()) {
+ QComposeTableElement nextElem = *(it + next);
+ if (isDuplicate(elem, nextElem)) {
+ elem = nextElem;
+ next++;
+ continue;
+ } else {
+ break;
+ }
+ }
+ break;
+ } while (true);
+
+ commitText(elem.value);
+ reset();
+
+ return true;
+}
+
+void QComposeInputContext::commitText(uint character) const
+{
+ QInputMethodEvent event;
+ event.setCommitString(QChar(character));
+ QCoreApplication::sendEvent(m_focusObject, &event);
+}
+
+bool QComposeInputContext::ignoreKey(int keyval) const
+{
+ for (uint i = 0; i < (sizeof(ignoreKeys) / sizeof(ignoreKeys[0])); i++)
+ if (keyval == ignoreKeys[i])
+ return true;
+
+ return false;
+}
+
+bool QComposeInputContext::composeKey(int keyval) const
+{
+ for (uint i = 0; i < (sizeof(composingKeys) / sizeof(composingKeys[0])); i++)
+ if (keyval == composingKeys[i])
+ return true;
+
+ return false;
+}
+
+void QComposeInputContext::clearComposeBuffer()
+{
+ for (uint i=0; i < (sizeof(m_composeBuffer) / sizeof(int)); i++)
+ m_composeBuffer[i] = 0;
+}
+
+QComposeInputContext::~QComposeInputContext() {}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
new file mode 100644
index 0000000000..1ced2f8ded
--- /dev/null
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMPOSEPLATFORMINPUTCONTEXT_H
+#define QCOMPOSEPLATFORMINPUTCONTEXT_H
+
+#include <qpa/qplatforminputcontext.h>
+
+#include <QtCore/QList>
+
+#include "generator/qtablegenerator.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEvent;
+
+class QComposeInputContext : public QPlatformInputContext
+{
+ Q_OBJECT
+
+public:
+ QComposeInputContext();
+ ~QComposeInputContext();
+
+ bool isValid() const;
+ void setFocusObject(QObject *object);
+ void reset();
+ void update(Qt::InputMethodQueries);
+ bool filterEvent(const QEvent *event);
+
+protected:
+ void clearComposeBuffer();
+ bool ignoreKey(int keyval) const;
+ bool composeKey(int keyval) const;
+ bool checkComposeTable();
+ void commitText(uint character) const;
+
+private:
+ QObject *m_focusObject;
+ QList<QComposeTableElement> m_composeTable;
+ uint m_composeBuffer[QT_KEYSEQUENCE_MAX_LEN + 1];
+ TableGenerator::TableState m_tableState;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOMPOSEPLATFORMINPUTCONTEXT_H
diff --git a/src/plugins/platforminputcontexts/compose/xkbcommon_workaround.h b/src/plugins/platforminputcontexts/compose/xkbcommon_workaround.h
new file mode 100644
index 0000000000..58ce143978
--- /dev/null
+++ b/src/plugins/platforminputcontexts/compose/xkbcommon_workaround.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XKBCOMMON_WORKAROUND_H
+#define XKBCOMMON_WORKAROUND_H
+
+// Function utf32_to_utf8() is borrowed from the libxkbcommon library,
+// file keysym-utf.c. The workaround should be removed once the fix from
+// https://bugs.freedesktop.org/show_bug.cgi?id=56780 gets released.
+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;
+}
+
+static bool needWorkaround(uint32_t sym)
+{
+ /* patch encoding botch */
+ if (sym == XKB_KEY_KP_Space)
+ return true;
+
+ /* special keysyms */
+ if ((sym >= XKB_KEY_BackSpace && sym <= XKB_KEY_Clear) ||
+ (sym >= XKB_KEY_KP_Multiply && sym <= XKB_KEY_KP_9) ||
+ sym == XKB_KEY_Return || sym == XKB_KEY_Escape ||
+ sym == XKB_KEY_Delete || sym == XKB_KEY_KP_Tab ||
+ sym == XKB_KEY_KP_Enter || sym == XKB_KEY_KP_Equal)
+ return true;
+
+ return false;
+}
+
+#endif // XKBCOMMON_WORKAROUND_H
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
index 7b3c6e9c36..fb58de5edc 100644
--- a/src/plugins/platforminputcontexts/platforminputcontexts.pro
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
@@ -1,4 +1,10 @@
TEMPLATE = subdirs
+
qtHaveModule(dbus) {
!mac:!win32:SUBDIRS += ibus maliit
}
+
+unix:!macx:contains(QT_CONFIG, xkbcommon): {
+ SUBDIRS += compose
+}
+
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp
index f8f077908c..ae94e75e34 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/src/androidjnimain.cpp
@@ -126,8 +126,6 @@ static int m_desktopHeightPixels = 0;
static volatile bool m_pauseApplication;
-static jmethodID m_setFullScreenMethodID = 0;
-
static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = 0;
@@ -272,24 +270,6 @@ namespace QtAndroid
return m_androidPlatformIntegration;
}
- void setFullScreen(QWidget *widget)
- {
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- bool fullScreen = widget->isFullScreen();
- if (!fullScreen) {
- foreach (QWidget *w, qApp->topLevelWidgets()) {
- fullScreen |= w->isFullScreen();
- if (fullScreen)
- break;
- }
- }
-
- env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, fullScreen);
- }
-
QWindow *topLevelWindowAt(const QPoint &globalPos)
{
return m_androidPlatformIntegration
@@ -674,9 +654,9 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
if (!m_androidPlatformIntegration)
return;
- if (qApp != 0) {
- foreach (QWidget *w, qApp->topLevelWidgets())
- w->update();
+ if (QGuiApplication::instance() != 0) {
+ foreach (QWindow *w, QGuiApplication::topLevelWindows())
+ QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry()));
}
#ifndef ANDROID_PLUGIN_OPENGL
@@ -763,7 +743,6 @@ static int registerNatives(JNIEnv *env)
}
GET_AND_CHECK_STATIC_METHOD(m_redrawSurfaceMethodID, m_applicationClass, "redrawSurface", "(IIII)V");
- GET_AND_CHECK_STATIC_METHOD(m_setFullScreenMethodID, m_applicationClass, "setFullScreen", "(Z)V");
#ifdef ANDROID_PLUGIN_OPENGL
FIND_AND_CHECK_CLASS("android/view/Surface");
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.cpp b/src/plugins/platforms/android/src/qandroidinputcontext.cpp
index 37fb605ea8..2180560b04 100644
--- a/src/plugins/platforms/android/src/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/src/qandroidinputcontext.cpp
@@ -337,7 +337,10 @@ void QAndroidInputContext::reset()
void QAndroidInputContext::commit()
{
finishComposingText();
+}
+void QAndroidInputContext::updateCursorPosition()
+{
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (!query.isNull()) {
const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
@@ -378,6 +381,12 @@ void QAndroidInputContext::showInputPanel()
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return;
+
+ disconnect(m_updateCursorPosConnection);
+ if (qGuiApp->focusObject()->metaObject()->indexOfSignal("cursorPositionChanged(int,int)") >= 0) // QLineEdit breaks the pattern
+ m_updateCursorPosConnection = connect(qGuiApp->focusObject(), SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateCursorPosition()));
+ else
+ m_updateCursorPosConnection = connect(qGuiApp->focusObject(), SIGNAL(cursorPositionChanged()), this, SLOT(updateCursorPosition()));
QRectF itemRect = qGuiApp->inputMethod()->inputItemRectangle();
QRect rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(itemRect).toRect();
QWindow *window = qGuiApp->focusWindow();
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.h b/src/plugins/platforms/android/src/qandroidinputcontext.h
index e2b8107044..482aeffa50 100644
--- a/src/plugins/platforms/android/src/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/src/qandroidinputcontext.h
@@ -119,10 +119,12 @@ private:
private slots:
virtual void sendEvent(QObject *receiver, QInputMethodEvent *event);
virtual void sendEvent(QObject *receiver, QInputMethodQueryEvent *event);
+ void updateCursorPosition();
private:
ExtractedText m_extractedText;
QString m_composingText;
+ QMetaObject::Connection m_updateCursorPosConnection;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri
index 9bf36b2337..76539b50ab 100644
--- a/src/plugins/platforms/android/src/src.pri
+++ b/src/plugins/platforms/android/src/src.pri
@@ -1,6 +1,6 @@
load(qt_plugin)
-QT += core-private gui-private widgets-private platformsupport-private
+QT += core-private gui-private platformsupport-private
CONFIG += qpa/genericunixfontdatabase
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 55f94df45a..e1569d4f44 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -202,6 +202,13 @@ static void cleanupCocoaApplicationDelegate()
if ([self canQuit]) {
if (!startedQuit) {
startedQuit = true;
+ // Close open windows. This is done in order to deliver de-expose
+ // events while the event loop is still running.
+ const QWindowList topLevels = QGuiApplication::topLevelWindows();
+ for (int i = 0; i < topLevels.size(); ++i) {
+ topLevels.at(i)->close();
+ }
+
QGuiApplication::exit(0);
startedQuit = false;
}
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 9cc0353dc6..297d81abab 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -586,7 +586,7 @@ QString QCocoaFileDialogHelper::directory() const
{
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
if (delegate)
- return QCFString::toQString([delegate->mSavePanel directory]);
+ return QCFString::toQString([[delegate->mSavePanel directoryURL] path]);
return QString();
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index d0fcf93b8c..3312de6e3f 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -90,11 +90,28 @@ void QCocoaScreen::updateGeometry()
{
NSScreen *nsScreen = osScreen();
NSRect frameRect = [nsScreen frame];
- m_geometry = QRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height);
- NSRect visibleRect = [nsScreen visibleFrame];
- m_availableGeometry = QRect(visibleRect.origin.x,
- frameRect.size.height - (visibleRect.origin.y + visibleRect.size.height), // invert y
- visibleRect.size.width, visibleRect.size.height);
+
+ if (m_screenIndex == 0) {
+ m_geometry = QRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height);
+ // This is the primary screen, the one that contains the menubar. Its origin should be
+ // (0, 0), and it's the only one whose available geometry differs from its full geometry.
+ NSRect visibleRect = [nsScreen visibleFrame];
+ m_availableGeometry = QRect(visibleRect.origin.x,
+ frameRect.size.height - (visibleRect.origin.y + visibleRect.size.height), // invert y
+ visibleRect.size.width, visibleRect.size.height);
+ } else {
+ // NSScreen origin is at the bottom-left corner, QScreen is at the top-left corner.
+ // When we get the NSScreen frame rect, we need to re-align its origin y coordinate
+ // w.r.t. the primary screen, whose origin is (0, 0).
+ NSRect r = [[[NSScreen screens] objectAtIndex:0] frame];
+ QRect referenceScreenGeometry = QRect(r.origin.x, r.origin.y, r.size.width, r.size.height);
+ m_geometry = QRect(frameRect.origin.x,
+ referenceScreenGeometry.height() - (frameRect.origin.y + frameRect.size.height),
+ frameRect.size.width, frameRect.size.height);
+
+ // Not primary screen. See above.
+ m_availableGeometry = m_geometry;
+ }
m_format = QImage::Format_RGB32;
m_depth = NSBitsPerPixelFromDepth([nsScreen depth]);
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.h b/src/plugins/platforms/cocoa/qcocoakeymapper.h
index 324b753131..0629de9317 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.h
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.h
@@ -99,7 +99,6 @@ private:
const UCKeyboardLayout *unicode;
void *other;
} keyboard_layout_format;
- KeyboardLayoutRef currentKeyboardLayout;
KeyboardLayoutKind keyboard_kind;
UInt32 keyboard_dead;
KeyboardLayoutItem *keyLayout[256];
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index bdcad6f490..40cffab3c9 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -195,7 +195,7 @@ NSMenuItem *QCocoaMenuItem::sync()
QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
switch (m_role) {
case ApplicationSpecificRole:
- mergeItem = [loader appSpecificMenuItem];
+ mergeItem = [loader appSpecificMenuItem:reinterpret_cast<NSInteger>(this)];
break;
case AboutRole:
mergeItem = [loader aboutMenuItem];
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h
index f95f684e8c..a45ec0fa89 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h
@@ -79,7 +79,7 @@
- (NSMenuItem *)aboutMenuItem;
- (NSMenuItem *)aboutQtMenuItem;
- (NSMenuItem *)hideMenuItem;
-- (NSMenuItem *)appSpecificMenuItem;
+- (NSMenuItem *)appSpecificMenuItem:(NSInteger)tag;
- (IBAction)terminate:(id)sender;
- (IBAction)orderFrontStandardAboutPanel:(id)sender;
- (IBAction)hideOtherApplications:(id)sender;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 2a9dcec64b..726fe5c6d2 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -246,11 +246,17 @@ QT_END_NAMESPACE
return [[hideItem retain] autorelease];
}
-- (NSMenuItem *)appSpecificMenuItem
+- (NSMenuItem *)appSpecificMenuItem:(NSInteger)tag
{
+ NSMenuItem *item = [appMenu itemWithTag:tag];
+
+ // No reason to create the item if it already exists. See QTBUG-27202.
+ if (item)
+ return [[item retain] autorelease];
+
// Create an App-Specific menu item, insert it into the menu and return
// it as an autorelease item.
- NSMenuItem *item = [[NSMenuItem alloc] init];
+ item = [[NSMenuItem alloc] init];
NSInteger location;
if (lastAppSpecificItem == nil) {
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 2f79b49534..ca84312059 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -52,6 +52,7 @@ class QWidget;
class QPlatformPrinterSupport;
class QPrintEngine;
class QPlatformMenu;
+class QPlatformMenuBar;
class QCocoaNativeInterface : public QPlatformNativeInterface
{
@@ -99,12 +100,27 @@ private:
// Dock menu support
static void setDockMenu(QPlatformMenu *platformMenu);
+ // Function to return NSMenu * from QPlatformMenu
+ static void *qMenuToNSMenu(QPlatformMenu *platformMenu);
+
+ // Function to return NSMenu * from QPlatformMenuBar
+ static void *qMenuBarToNSMenu(QPlatformMenuBar *platformMenuBar);
+
// QImage <-> CGImage conversion functions
static CGImageRef qImageToCGImage(const QImage &image);
static QImage cgImageToQImage(CGImageRef image);
// Embedding NSViews as child QWindows
static void setWindowContentView(QPlatformWindow *window, void *nsViewContentView);
+
+ // Register if a window should deliver touch events. Enabling
+ // touch events has implications for delivery of other events,
+ // for example by causing scrolling event lag.
+ //
+ // The registration is ref-counted: multiple widgets can enable
+ // touch events, which then will be delivered until the widget
+ // deregisters.
+ static void registerTouchWindow(QWindow *window, bool enable);
};
#endif // QCOCOANATIVEINTERFACE_H
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 9990537c1f..ededb63487 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -109,12 +109,18 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerDraggedTypes);
if (resource.toLower() == "setdockmenu")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setDockMenu);
+ if (resource.toLower() == "qmenutonsmenu")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::qMenuToNSMenu);
+ if (resource.toLower() == "qmenubartonsmenu")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::qMenuBarToNSMenu);
if (resource.toLower() == "qimagetocgimage")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::qImageToCGImage);
if (resource.toLower() == "cgimagetoqimage")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::cgImageToQImage);
if (resource.toLower() == "setwindowcontentview")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setWindowContentView);
+ if (resource.toLower() == "registertouchwindow")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerTouchWindow);
return 0;
}
@@ -187,7 +193,24 @@ void QCocoaNativeInterface::setDockMenu(QPlatformMenu *platformMenu)
QCocoaMenu *cocoaPlatformMenu = static_cast<QCocoaMenu *>(platformMenu);
NSMenu *menu = cocoaPlatformMenu->nsMenu();
// setDockMenu seems to be undocumented, but this is what Qt 4 did.
- [NSApp setDockMenu: menu];
+ if ([NSApp respondsToSelector:@selector(setDockMenu:)])
+ [NSApp setDockMenu: menu];
+ else
+ qWarning("Could not set dock menu: [NSApp setDockMenu] is not available.");
+}
+
+void *QCocoaNativeInterface::qMenuToNSMenu(QPlatformMenu *platformMenu)
+{
+ QCocoaMenu *cocoaPlatformMenu = static_cast<QCocoaMenu *>(platformMenu);
+ NSMenu *menu = cocoaPlatformMenu->nsMenu();
+ return reinterpret_cast<void *>(menu);
+}
+
+void *QCocoaNativeInterface::qMenuBarToNSMenu(QPlatformMenuBar *platformMenuBar)
+{
+ QCocoaMenuBar *cocoaPlatformMenuBar = static_cast<QCocoaMenuBar *>(platformMenuBar);
+ NSMenu *menu = cocoaPlatformMenuBar->nsMenu();
+ return reinterpret_cast<void *>(menu);
}
CGImageRef QCocoaNativeInterface::qImageToCGImage(const QImage &image)
@@ -206,4 +229,11 @@ void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void *
cocoaPlatformWindow->setContentView(reinterpret_cast<NSView *>(contentView));
}
+void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable)
+{
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ cocoaWindow->registerTouch(enable);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index 6f8d0fa22a..8b0c14a984 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -179,14 +179,14 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
if (mac_widget_colors[i].active != 0) {
qc = qt_mac_colorForThemeTextColor(mac_widget_colors[i].active);
pal.setColor(QPalette::Active, QPalette::Text, qc);
+ pal.setColor(QPalette::Inactive, QPalette::Text, qc);
pal.setColor(QPalette::Active, QPalette::WindowText, qc);
+ pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
+ pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
qc = qt_mac_colorForThemeTextColor(mac_widget_colors[i].inactive);
- pal.setColor(QPalette::Inactive, QPalette::Text, qc);
pal.setColor(QPalette::Disabled, QPalette::Text, qc);
- pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
- pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
}
if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette) {
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 84dcaad206..e1de5f0add 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -108,6 +108,8 @@ public:
void setWindowIcon(const QIcon &icon);
void raise();
void lower();
+ bool isExposed() const;
+ bool isOpaque() const;
void propagateSizeHints();
void setOpacity(qreal level);
void setMask(const QRegion &region);
@@ -145,7 +147,12 @@ public:
void setMenubar(QCocoaMenuBar *mb);
QCocoaMenuBar *menubar() const;
+ void registerTouch(bool enable);
+
qreal devicePixelRatio() const;
+ void exposeWindow();
+ void obscureWindow();
+ QWindow *childWindowAt(QPoint windowPoint);
protected:
// NSWindow handling. The QCocoaWindow/QNSView can either be displayed
// in an existing NSWindow or in one created by Qt.
@@ -158,8 +165,6 @@ protected:
QCocoaWindow *parentCocoaWindow() const;
void syncWindowState(Qt::WindowState newState);
- void updateOpaque();
-
// private:
public: // for QNSView
friend class QCocoaBackingStore;
@@ -175,6 +180,7 @@ public: // for QNSView
Qt::WindowState m_synchedWindowState;
Qt::WindowModality m_windowModality;
QPointer<QWindow> m_activePopupWindow;
+ QPointer<QWindow> m_underMouseWindow;
bool m_inConstructor;
QCocoaGLContext *m_glContext;
@@ -182,6 +188,8 @@ public: // for QNSView
bool m_hasModalSession;
bool m_frameStrutEventsEnabled;
+ bool m_isExposed;
+ int m_registerTouchCount;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 5eab036661..e74f9dcfe0 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -200,6 +200,8 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_menubar(0)
, m_hasModalSession(false)
, m_frameStrutEventsEnabled(false)
+ , m_isExposed(false)
+ , m_registerTouchCount(0)
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@@ -260,6 +262,9 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
void QCocoaWindow::setVisible(bool visible)
{
QCocoaAutoReleasePool pool;
+ QCocoaWindow *parentCocoaWindow = 0;
+ if (window()->transientParent())
+ parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle());
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::setVisible" << window() << visible;
#endif
@@ -267,10 +272,7 @@ void QCocoaWindow::setVisible(bool visible)
// We need to recreate if the modality has changed as the style mask will need updating
if (m_windowModality != window()->modality())
recreateWindow(parent());
- QCocoaWindow *parentCocoaWindow = 0;
- if (window()->transientParent()) {
- parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle());
-
+ if (parentCocoaWindow) {
// The parent window might have moved while this window was hidden,
// update the window geometry if there is a parent.
setGeometry(window()->geometry());
@@ -280,13 +282,20 @@ void QCocoaWindow::setVisible(bool visible)
if (window()->type() == Qt::Popup) {
// qDebug() << "transientParent and popup" << window()->type() << Qt::Popup << (window()->type() & Qt::Popup);
parentCocoaWindow->m_activePopupWindow = window();
+ // 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
+ [parentCocoaWindow->m_nsWindow setStyleMask:
+ (parentCocoaWindow->windowStyleMask(parentCocoaWindow->m_windowFlags) & ~NSResizableWindowMask)];
}
}
- // Make sure the QWindow has a frame ready before we show the NSWindow.
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
- QWindowSystemInterface::flushWindowSystemEvents();
+ // This call is here to handle initial window show correctly:
+ // - top-level windows need to have backing store content ready when the
+ // window is shown, sendin the expose event here makes that more likely.
+ // - QNSViews for child windows are initialy not hidden and won't get the
+ // viewDidUnhide message.
+ exposeWindow();
if (m_nsWindow) {
// setWindowState might have been called while the window was hidden and
@@ -338,8 +347,9 @@ void QCocoaWindow::setVisible(bool visible)
} else {
[m_contentView setHidden:YES];
}
- if (!QCoreApplication::closingDown())
- QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+ if (parentCocoaWindow && window()->type() == Qt::Popup)
+ // QTBUG-30266: a window should not be resizable while a transient popup is open
+ [parentCocoaWindow->m_nsWindow setStyleMask:parentCocoaWindow->windowStyleMask(parentCocoaWindow->m_windowFlags)];
}
}
@@ -376,7 +386,7 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
NSInteger styleMask = NSBorderlessWindowMask;
if ((type & Qt::Popup) == Qt::Popup) {
- if (!windowIsPopupType(type))
+ if (!windowIsPopupType(type) && !(flags & Qt::FramelessWindowHint))
styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSTitledWindowMask);
} else {
@@ -491,6 +501,19 @@ void QCocoaWindow::lower()
[m_nsWindow orderBack: m_nsWindow];
}
+bool QCocoaWindow::isExposed() const
+{
+ return m_isExposed;
+}
+
+bool QCocoaWindow::isOpaque() const
+{
+ bool translucent = (window()->format().alphaBufferSize() > 0
+ || window()->opacity() < 1
+ || (m_qtView && [m_qtView hasMask]));
+ return !translucent;
+}
+
void QCocoaWindow::propagateSizeHints()
{
QCocoaAutoReleasePool pool;
@@ -529,20 +552,11 @@ void QCocoaWindow::propagateSizeHints()
}
}
-void QCocoaWindow::updateOpaque()
-{
- bool translucent = window()->format().alphaBufferSize() > 0
- || window()->opacity() < 1
- || (m_contentView && [m_contentView hasMask]);
- [m_nsWindow setOpaque:!translucent];
-}
-
-
void QCocoaWindow::setOpacity(qreal level)
{
if (m_nsWindow) {
[m_nsWindow setAlphaValue:level];
- updateOpaque();
+ [m_nsWindow setOpaque: isOpaque()];
}
}
@@ -552,7 +566,7 @@ void QCocoaWindow::setMask(const QRegion &region)
[m_nsWindow setBackgroundColor:[NSColor clearColor]];
[m_qtView setMaskRegion:&region];
- updateOpaque();
+ [m_nsWindow setOpaque: isOpaque()];
}
bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
@@ -886,6 +900,15 @@ QCocoaMenuBar *QCocoaWindow::menubar() const
return m_menubar;
}
+void QCocoaWindow::registerTouch(bool enable)
+{
+ m_registerTouchCount += enable ? 1 : -1;
+ if (m_registerTouchCount == 1)
+ [m_contentView setAcceptsTouchEvents:YES];
+ else if (m_registerTouchCount == 0)
+ [m_contentView setAcceptsTouchEvents:NO];
+}
+
qreal QCocoaWindow::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
@@ -898,6 +921,37 @@ qreal QCocoaWindow::devicePixelRatio() const
}
}
+void QCocoaWindow::exposeWindow()
+{
+ if (!m_isExposed) {
+ m_isExposed = true;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+ }
+}
+
+void QCocoaWindow::obscureWindow()
+{
+ if (m_isExposed) {
+ m_isExposed = false;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+ }
+}
+
+QWindow *QCocoaWindow::childWindowAt(QPoint windowPoint)
+{
+ QWindow *targetWindow = window();
+ foreach (QObject *child, targetWindow->children()) {
+ if (QWindow *childWindow = qobject_cast<QWindow *>(child)) {
+ if (childWindow->geometry().contains(windowPoint)) {
+ QCocoaWindow* platformWindow = static_cast<QCocoaWindow*>(childWindow->handle());
+ targetWindow = platformWindow->childWindowAt(windowPoint - childWindow->position());
+ }
+ }
+ }
+
+ return targetWindow;
+}
+
QMargins QCocoaWindow::frameMargins() const
{
NSRect frameW = [m_nsWindow frame];
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 5fe0861e0a..e7ea3d8f8d 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -59,6 +59,7 @@ QT_END_NAMESPACE
QPoint m_backingStoreOffset;
CGImageRef m_maskImage;
uchar *m_maskData;
+ bool m_shouldInvalidateWindowShadow;
QWindow *m_window;
QCocoaWindow *m_platformWindow;
Qt::MouseButtons m_buttons;
@@ -76,14 +77,18 @@ QT_END_NAMESPACE
- (void)setQCocoaGLContext:(QCocoaGLContext *)context;
- (void)flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset;
- (void)setMaskRegion:(const QRegion *)region;
+- (void)invalidateWindowShadowIfNeeded;
- (void)drawRect:(NSRect)dirtyRect;
- (void)updateGeometry;
- (void)windowNotification : (NSNotification *) windowNotification;
+- (void)viewDidHide;
+- (void)viewDidUnhide;
- (BOOL)isFlipped;
- (BOOL)acceptsFirstResponder;
- (BOOL)becomeFirstResponder;
- (BOOL)hasMask;
+- (BOOL)isOpaque;
- (void)resetMouseButtons;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 18714ddbae..3046b898df 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -80,6 +80,7 @@ static QTouchDevice *touchDevice = 0;
m_backingStore = 0;
m_maskImage = 0;
m_maskData = 0;
+ m_shouldInvalidateWindowShadow = false;
m_window = 0;
m_buttons = Qt::NoButton;
m_sendKeyEvent = false;
@@ -240,6 +241,7 @@ static QTouchDevice *touchDevice = 0;
// Send a geometry change event to Qt, if it's ready to handle events
if (!m_platformWindow->m_inConstructor) {
QWindowSystemInterface::handleGeometryChange(m_window, geometry);
+ QWindowSystemInterface::handleExposeEvent(m_window, geometry);
QWindowSystemInterface::flushWindowSystemEvents();
}
}
@@ -266,10 +268,10 @@ static QTouchDevice *touchDevice = 0;
QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowMinimized);
} else if (notificationName == NSWindowDidDeminiaturizeNotification) {
QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowNoState);
- // Qt expects an expose event after restore/deminiaturize. This also needs
- // to be a non-synchronous event to make sure it gets processed after
- // the state change event sent above.
- QWindowSystemInterface::handleExposeEvent(m_window, QRegion(m_window->geometry()));
+ } else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
+ m_platformWindow->obscureWindow();
+ } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
+ m_platformWindow->exposeWindow();
} else {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
@@ -285,6 +287,16 @@ static QTouchDevice *touchDevice = 0;
}
}
+- (void)viewDidHide
+{
+ m_platformWindow->obscureWindow();
+}
+
+- (void)viewDidUnhide
+{
+ m_platformWindow->exposeWindow();
+}
+
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
{
m_backingStore = backingStore;
@@ -298,15 +310,21 @@ static QTouchDevice *touchDevice = 0;
return m_maskData != 0;
}
+- (BOOL) isOpaque
+{
+ return m_platformWindow->isOpaque();
+}
+
- (void) setMaskRegion:(const QRegion *)region
{
+ m_shouldInvalidateWindowShadow = true;
if (m_maskImage)
CGImageRelease(m_maskImage);
if (region->isEmpty()) {
m_maskImage = 0;
}
- const QRect &rect = qt_mac_toQRect([self frame]);
+ const QRect &rect = region->boundingRect();
QImage maskImage(rect.size(), QImage::Format_RGB888);
maskImage.fill(Qt::white);
QPainter p(&maskImage);
@@ -319,6 +337,14 @@ static QTouchDevice *touchDevice = 0;
m_maskImage = qt_mac_toCGImage(maskImage, true, &m_maskData);
}
+- (void)invalidateWindowShadowIfNeeded
+{
+ if (m_shouldInvalidateWindowShadow && m_platformWindow->m_nsWindow) {
+ [m_platformWindow->m_nsWindow invalidateShadow];
+ m_shouldInvalidateWindowShadow = false;
+ }
+}
+
- (void) drawRect:(NSRect)dirtyRect
{
if (!m_backingStore)
@@ -373,6 +399,8 @@ static QTouchDevice *touchDevice = 0;
CGContextRestoreGState(cgContext);
CGImageRelease(cleanImg);
CGImageRelease(subMask);
+
+ [self invalidateWindowShadowIfNeeded];
}
- (BOOL) isFlipped
@@ -382,6 +410,8 @@ static QTouchDevice *touchDevice = 0;
- (BOOL)becomeFirstResponder
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return NO;
QWindow *focusWindow = m_window;
// For widgets we need to do a bit of trickery as the window
@@ -399,6 +429,8 @@ static QTouchDevice *touchDevice = 0;
{
if (m_window->flags() & Qt::WindowDoesNotAcceptFocus)
return NO;
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return NO;
if ((m_window->flags() & Qt::ToolTip) == Qt::ToolTip)
return NO;
return YES;
@@ -406,7 +438,9 @@ static QTouchDevice *touchDevice = 0;
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
- Q_UNUSED(theEvent);
+ Q_UNUSED(theEvent)
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return NO;
return YES;
}
@@ -511,6 +545,8 @@ static QTouchDevice *touchDevice = 0;
- (void)mouseDown:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super mouseDown:theEvent];
m_sendUpAsRightButton = false;
if (m_platformWindow->m_activePopupWindow) {
QWindowSystemInterface::handleCloseEvent(m_platformWindow->m_activePopupWindow);
@@ -535,6 +571,8 @@ static QTouchDevice *touchDevice = 0;
- (void)mouseDragged:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super mouseDragged:theEvent];
if (!(m_buttons & Qt::LeftButton))
qWarning("QNSView mouseDragged: Internal mouse button tracking invalid (missing Qt::LeftButton)");
[self handleMouseEvent:theEvent];
@@ -542,6 +580,8 @@ static QTouchDevice *touchDevice = 0;
- (void)mouseUp:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super mouseUp:theEvent];
if (m_sendUpAsRightButton) {
m_buttons &= ~Qt::RightButton;
m_sendUpAsRightButton = false;
@@ -559,6 +599,7 @@ static QTouchDevice *touchDevice = 0;
if (NSIsEmptyRect([self visibleRect]))
return;
+ // Remove current trakcing areas:
QCocoaAutoReleasePool pool;
if (NSArray *trackingArray = [self trackingAreas]) {
NSUInteger size = [trackingArray count];
@@ -571,7 +612,7 @@ static QTouchDevice *touchDevice = 0;
// Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should
// only be turned on if mouseTracking, hover is on or a tool tip is set.
// Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to
- // turn it on in ALL case. That means EVERY QCocoaView gets to pay the cost of
+ // turn it on in ALL case. That means EVERY QWindow gets to pay the cost of
// mouse moves delivered to it (Apple recommends keeping it OFF because there
// is a performance hit). So it goes.
NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp
@@ -586,30 +627,74 @@ static QTouchDevice *touchDevice = 0;
- (void)mouseMoved:(NSEvent *)theEvent
{
- [self handleMouseEvent:theEvent];
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super mouseMoved:theEvent];
+
+ QPoint windowPoint, screenPoint;
+ [self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint);
+
+ // Top-level windows generate enter-leave events for sub-windows.
+ // Qt wants to know which window (if any) will be entered at the
+ // the time of the leave. This is dificult to accomplish by
+ // handling mouseEnter and mouseLeave envents, since they are sent
+ // individually to different views.
+ if (m_platformWindow->m_nsWindow && childWindow) {
+ if (childWindow != m_platformWindow->m_underMouseWindow) {
+ QWindowSystemInterface::handleEnterLeaveEvent(childWindow, m_platformWindow->m_underMouseWindow, windowPoint, screenPoint);
+ m_platformWindow->m_underMouseWindow = childWindow;
+ }
+ }
+
+ // Cocoa keeps firing mouse move events for obscured parent views. Qt should not
+ // send those events so filter them out here.
+ if (childWindow != m_window)
+ return;
+
+ [self handleMouseEvent: theEvent];
}
- (void)mouseEntered:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super mouseEntered:theEvent];
+
+ // Top-level windows generate enter events for sub-windows.
+ if (!m_platformWindow->m_nsWindow)
+ return;
+
QPoint windowPoint, screenPoint;
[self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindowSystemInterface::handleEnterEvent(m_window, windowPoint, screenPoint);
+ m_platformWindow->m_underMouseWindow = m_platformWindow->childWindowAt(windowPoint);
+ QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_underMouseWindow, windowPoint, screenPoint);
}
- (void)mouseExited:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super mouseExited:theEvent];
Q_UNUSED(theEvent);
- QWindowSystemInterface::handleLeaveEvent(m_window);
+
+ // Top-level windows generate leave events for sub-windows.
+ if (!m_platformWindow->m_nsWindow)
+ return;
+
+ QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_underMouseWindow);
+ m_platformWindow->m_underMouseWindow = 0;
}
- (void)rightMouseDown:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super rightMouseDown:theEvent];
m_buttons |= Qt::RightButton;
[self handleMouseEvent:theEvent];
}
- (void)rightMouseDragged:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super rightMouseDragged:theEvent];
if (!(m_buttons & Qt::RightButton))
qWarning("QNSView rightMouseDragged: Internal mouse button tracking invalid (missing Qt::RightButton)");
[self handleMouseEvent:theEvent];
@@ -617,18 +702,24 @@ static QTouchDevice *touchDevice = 0;
- (void)rightMouseUp:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super rightMouseUp:theEvent];
m_buttons &= ~Qt::RightButton;
[self handleMouseEvent:theEvent];
}
- (void)otherMouseDown:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super otherMouseDown:theEvent];
m_buttons |= cocoaButton2QtButton([theEvent buttonNumber]);
[self handleMouseEvent:theEvent];
}
- (void)otherMouseDragged:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super otherMouseDragged:theEvent];
if (!(m_buttons & ~(Qt::LeftButton | Qt::RightButton)))
qWarning("QNSView otherMouseDragged: Internal mouse button tracking invalid (missing Qt::MiddleButton or Qt::ExtraButton*)");
[self handleMouseEvent:theEvent];
@@ -636,6 +727,8 @@ static QTouchDevice *touchDevice = 0;
- (void)otherMouseUp:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super otherMouseUp:theEvent];
m_buttons &= ~cocoaButton2QtButton([theEvent buttonNumber]);
[self handleMouseEvent:theEvent];
}
@@ -671,6 +764,8 @@ static QTouchDevice *touchDevice = 0;
#ifndef QT_NO_WHEELEVENT
- (void)scrollWheel:(NSEvent *)theEvent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super scrollWheel:theEvent];
const EventRef carbonEvent = (EventRef)[theEvent eventRef];
const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
const bool scrollEvent = carbonEventKind == kEventMouseScroll;
@@ -778,6 +873,7 @@ static QTouchDevice *touchDevice = 0;
ulong nativeModifiers = [nsevent modifierFlags];
Qt::KeyboardModifiers modifiers = [self convertKeyModifiers: nativeModifiers];
NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers];
+ NSString *characters = [nsevent characters];
// [from Qt 4 impl] There is no way to get the scan code from carbon. But we cannot
// use the value 0, since it indicates that the event originates from somewhere
@@ -790,9 +886,12 @@ static QTouchDevice *touchDevice = 0;
QChar ch;
int keyCode;
- if ([charactersIgnoringModifiers length] > 0) {
- // convert the first character into a key code
- ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
+ if ([charactersIgnoringModifiers length] > 0) { // convert the first character into a key code
+ if ((modifiers & Qt::ControlModifier) && ([characters length] != 0)) {
+ ch = QChar([characters characterAtIndex:0]);
+ } else {
+ ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
+ }
keyCode = [self convertKeyCode:ch];
} else {
// might be a dead key
@@ -808,7 +907,7 @@ static QTouchDevice *touchDevice = 0;
// ignore text for the U+F700-U+F8FF range. This is used by Cocoa when
// delivering function keys (e.g. arrow keys, backspace, F1-F35, etc.)
if ([charactersIgnoringModifiers length] == 1 && (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff))
- text = QCFString::toQString([nsevent characters]);
+ text = QCFString::toQString(characters);
if (m_composingText.isEmpty())
m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(m_window, timestamp, keyCode, modifiers, text);
@@ -836,11 +935,15 @@ static QTouchDevice *touchDevice = 0;
- (void)keyDown:(NSEvent *)nsevent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super keyDown:nsevent];
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
}
- (void)keyUp:(NSEvent *)nsevent
{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super keyUp:nsevent];
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)];
}
diff --git a/src/plugins/platforms/qnx/qqnxabstractnavigator.cpp b/src/plugins/platforms/qnx/qqnxabstractnavigator.cpp
index 08da98d690..5a94bff14e 100644
--- a/src/plugins/platforms/qnx/qqnxabstractnavigator.cpp
+++ b/src/plugins/platforms/qnx/qqnxabstractnavigator.cpp
@@ -44,7 +44,7 @@
#include <QDebug>
#include <QUrl>
-#ifdef QQNXNAVIGATOR_DEBUG
+#if defined(QQNXNAVIGATOR_DEBUG)
#define qNavigatorDebug qDebug
#else
#define qNavigatorDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
index 2ef548f59f..26543a8d56 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
@@ -53,7 +53,7 @@
#include <bps/navigator.h>
#include <bps/screen.h>
-#ifdef QQNXBPSEVENTFILTER_DEBUG
+#if defined(QQNXBPSEVENTFILTER_DEBUG)
#define qBpsEventFilterDebug qDebug
#else
#define qBpsEventFilterDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxbuffer.cpp b/src/plugins/platforms/qnx/qqnxbuffer.cpp
index 9007af7f70..c5e99a2001 100644
--- a/src/plugins/platforms/qnx/qqnxbuffer.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuffer.cpp
@@ -46,7 +46,7 @@
#include <errno.h>
#include <sys/mman.h>
-#ifdef QQNXBUFFER_DEBUG
+#if defined(QQNXBUFFER_DEBUG)
#define qBufferDebug qDebug
#else
#define qBufferDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp b/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
index 152b732556..2f531efd8b 100644
--- a/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
@@ -49,7 +49,7 @@
#include <QtCore/QSocketNotifier>
#include <QtCore/private/qcore_unix_p.h>
-#ifdef QQNXBUTTON_DEBUG
+#if defined(QQNXBUTTON_DEBUG)
#define qButtonDebug qDebug
#else
#define qButtonDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxclipboard.cpp b/src/plugins/platforms/qnx/qqnxclipboard.cpp
index 8286febd35..dfd1345eed 100644
--- a/src/plugins/platforms/qnx/qqnxclipboard.cpp
+++ b/src/plugins/platforms/qnx/qqnxclipboard.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#ifndef QT_NO_CLIPBOARD
+#if !defined(QT_NO_CLIPBOARD)
#include "qqnxclipboard.h"
@@ -53,7 +53,7 @@
#include <clipboard/clipboard.h>
#include <errno.h>
-#ifdef QQNXCLIPBOARD_DEBUG
+#if defined(QQNXCLIPBOARD_DEBUG)
#define qClipboardDebug qDebug
#else
#define qClipboardDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxclipboard.h b/src/plugins/platforms/qnx/qqnxclipboard.h
index e069355adc..561b57299e 100644
--- a/src/plugins/platforms/qnx/qqnxclipboard.h
+++ b/src/plugins/platforms/qnx/qqnxclipboard.h
@@ -44,7 +44,7 @@
#include <QtCore/qglobal.h>
-#ifndef QT_NO_CLIPBOARD
+#if !defined(QT_NO_CLIPBOARD)
#include <qpa/qplatformclipboard.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxcursor.cpp b/src/plugins/platforms/qnx/qqnxcursor.cpp
index 4fdff666d7..3cf857bb27 100644
--- a/src/plugins/platforms/qnx/qqnxcursor.cpp
+++ b/src/plugins/platforms/qnx/qqnxcursor.cpp
@@ -43,7 +43,7 @@
#include <QtCore/QDebug>
-#ifdef QQNXCURSOR_DEBUG
+#if defined(QQNXCURSOR_DEBUG)
#define qCursorDebug qDebug
#else
#define qCursorDebug QT_NO_QDEBUG_MACRO
@@ -55,7 +55,7 @@ QQnxCursor::QQnxCursor()
{
}
-#ifndef QT_NO_CURSOR
+#if !defined(QT_NO_CURSOR)
void QQnxCursor::changeCursor(QCursor *windowCursor, QWindow *window)
{
Q_UNUSED(windowCursor);
diff --git a/src/plugins/platforms/qnx/qqnxcursor.h b/src/plugins/platforms/qnx/qqnxcursor.h
index 5d6a8b2c30..b62c299040 100644
--- a/src/plugins/platforms/qnx/qqnxcursor.h
+++ b/src/plugins/platforms/qnx/qqnxcursor.h
@@ -51,7 +51,7 @@ class QQnxCursor : public QPlatformCursor
public:
QQnxCursor();
-#ifndef QT_NO_CURSOR
+#if !defined(QT_NO_CURSOR)
void changeCursor(QCursor *windowCursor, QWindow *window);
#endif
void setPos(const QPoint &pos);
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
index 4f61e0c587..12e8d8afbf 100644
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
@@ -51,7 +51,7 @@
#include <QTimer>
#include <QWindow>
-#ifdef QQNXFILEDIALOGHELPER_DEBUG
+#if defined(QQNXFILEDIALOGHELPER_DEBUG)
#define qFileDialogHelperDebug qDebug
#else
#define qFileDialogHelperDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 1c2ec23fa9..f77bb73614 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -50,7 +50,7 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
-#ifdef QQNXGLCONTEXT_DEBUG
+#if defined(QQNXGLCONTEXT_DEBUG)
#define qGLContextDebug qDebug
#else
#define qGLContextDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
index 0d8f430c73..97a361158e 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
@@ -61,13 +61,13 @@
#include <process.h>
#include <sys/keycodes.h>
-#ifdef QQNXINPUTCONTEXT_IMF_EVENT_DEBUG
+#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG)
#define qInputContextIMFEventDebug qDebug
#else
#define qInputContextIMFEventDebug QT_NO_QDEBUG_MACRO
#endif
-#ifdef QQNXINPUTCONTEXT_DEBUG
+#if defined(QQNXINPUTCONTEXT_DEBUG)
#define qInputContextDebug qDebug
#else
#define qInputContextDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
index 71b925357a..f444d34b5e 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
@@ -47,7 +47,7 @@
#include <QtCore/QDebug>
#include <QtGui/QGuiApplication>
-#ifdef QQNXINPUTCONTEXT_DEBUG
+#if defined(QQNXINPUTCONTEXT_DEBUG)
#define qInputContextDebug qDebug
#else
#define qInputContextDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 2d5c2e54e7..5ea4fef698 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -96,7 +96,7 @@
#include <errno.h>
-#ifdef QQNXINTEGRATION_DEBUG
+#if defined(QQNXINTEGRATION_DEBUG)
#define qIntegrationDebug qDebug
#else
#define qIntegrationDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
index d561482b47..30dbb330d7 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
@@ -45,7 +45,7 @@
#include <QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
-#ifdef QQNXNAVIGATOREVENTHANDLER_DEBUG
+#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG)
#define qNavigatorEventHandlerDebug qDebug
#else
#define qNavigatorEventHandlerDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
index 9fa8294815..640944fb45 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
@@ -55,7 +55,7 @@
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef QQNXNAVIGATOREVENTNOTIFIER_DEBUG
+#if defined(QQNXNAVIGATOREVENTNOTIFIER_DEBUG)
#define qNavigatorEventNotifierDebug qDebug
#else
#define qNavigatorEventNotifierDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp b/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
index 92a94e0a39..1656ab029b 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
@@ -44,7 +44,7 @@
#include <QDebug>
#include <private/qcore_unix_p.h>
-#ifdef QQNXNAVIGATOR_DEBUG
+#if defined(QQNXNAVIGATOR_DEBUG)
#define qNavigatorDebug qDebug
#else
#define qNavigatorDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
index 47a72f173b..7204e5bce9 100644
--- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
@@ -46,7 +46,7 @@
#include <errno.h>
-#ifdef QQNXRASTERBACKINGSTORE_DEBUG
+#if defined(QQNXRASTERBACKINGSTORE_DEBUG)
#define qRasterBackingStoreDebug qDebug
#else
#define qRasterBackingStoreDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxrootwindow.cpp b/src/plugins/platforms/qnx/qqnxrootwindow.cpp
index b01d468647..198801a832 100644
--- a/src/plugins/platforms/qnx/qqnxrootwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrootwindow.cpp
@@ -46,7 +46,7 @@
#include <QtCore/QUuid>
#include <QtCore/QDebug>
-#ifdef QQNXROOTWINDOW_DEBUG
+#if defined(QQNXROOTWINDOW_DEBUG)
#define qRootWindowDebug qDebug
#else
#define qRootWindowDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index f9efbde40c..7614abdc6a 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -49,7 +49,7 @@
#include <errno.h>
-#ifdef QQNXSCREEN_DEBUG
+#if defined(QQNXSCREEN_DEBUG)
#define qScreenDebug qDebug
#else
#define qScreenDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index 2d3c7608bf..57cfdc5eb6 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -50,7 +50,7 @@
#include <errno.h>
#include <sys/keycodes.h>
-#ifdef QQNXSCREENEVENT_DEBUG
+#if defined(QQNXSCREENEVENT_DEBUG)
#define qScreenEventDebug qDebug
#else
#define qScreenEventDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
index 8f262a7083..f3f660bc03 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
@@ -49,7 +49,7 @@
#include <cctype>
-#ifdef QQNXSCREENEVENTTHREAD_DEBUG
+#if defined(QQNXSCREENEVENTTHREAD_DEBUG)
#define qScreenEventThreadDebug qDebug
#else
#define qScreenEventThreadDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxtheme.cpp b/src/plugins/platforms/qnx/qqnxtheme.cpp
index ae9acd845e..c0aef07bd9 100644
--- a/src/plugins/platforms/qnx/qqnxtheme.cpp
+++ b/src/plugins/platforms/qnx/qqnxtheme.cpp
@@ -76,10 +76,11 @@ QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) co
switch (type) {
case QPlatformTheme::FileDialog:
return new QQnxFileDialogHelper(m_integration);
-#ifndef QT_NO_COLORDIALOG
+#endif
+#if !defined(QT_NO_COLORDIALOG)
case QPlatformTheme::ColorDialog:
#endif
-#ifndef QT_NO_FONTDIALOG
+#if !defined(QT_NO_FONTDIALOG)
case QPlatformTheme::FontDialog:
#endif
default:
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
index 3d2f49aa6c..11eb4a5082 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
@@ -47,7 +47,7 @@
#include <bps/locale.h>
#include <bps/virtualkeyboard.h>
-#ifdef QQNXVIRTUALKEYBOARD_DEBUG
+#if defined(QQNXVIRTUALKEYBOARD_DEBUG)
#define qVirtualKeyboardDebug qDebug
#else
#define qVirtualKeyboardDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
index ab912927bb..e810b47c22 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
@@ -56,7 +56,7 @@
#include <sys/types.h>
#include <unistd.h>
-#ifdef QQNXVIRTUALKEYBOARD_DEBUG
+#if defined(QQNXVIRTUALKEYBOARD_DEBUG)
#define qVirtualKeyboardDebug qDebug
#else
#define qVirtualKeyboardDebug QT_NO_QDEBUG_MACRO
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
index eb41b2efd0..6048868b08 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef VIRTUALKEYBOARDPPS_H_
-#define VIRTUALKEYBOARDPPS_H_
+#ifndef VIRTUALKEYBOARDPPS_H
+#define VIRTUALKEYBOARDPPS_H
#include "qqnxabstractvirtualkeyboard.h"
@@ -97,4 +97,4 @@ private:
static const size_t ms_bufferSize;
};
-#endif /* VIRTUALKEYBOARDPPS_H_ */
+#endif // VIRTUALKEYBOARDPPS_H
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 51435a1e55..f1bebee9b2 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qqnxwindow.h"
-#ifndef QT_NO_OPENGL
+#if !defined(QT_NO_OPENGL)
#include "qqnxglcontext.h"
#endif
#include "qqnxintegration.h"
@@ -53,12 +53,12 @@
#include <errno.h>
-#ifdef Q_OS_BLACKBERRY
+#if defined(Q_OS_BLACKBERRY)
#include <sys/pps.h>
#include <bps/navigator.h>
#endif
-#ifdef QQNXWINDOW_DEBUG
+#if defined(QQNXWINDOW_DEBUG)
#define qWindowDebug qDebug
#else
#define qWindowDebug QT_NO_QDEBUG_MACRO
@@ -72,7 +72,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context)
m_window(0),
m_currentBufferIndex(-1),
m_previousBufferIndex(-1),
-#ifndef QT_NO_OPENGL
+#if !defined(QT_NO_OPENGL)
m_platformOpenGLContext(0),
#endif
m_screen(0),
@@ -353,7 +353,7 @@ void QQnxWindow::setBufferSize(const QSize &size)
// Create window buffers if they do not exist
if (m_bufferSize.isEmpty()) {
-#ifndef QT_NO_OPENGL
+#if !defined(QT_NO_OPENGL)
// Get pixel format from EGL config if using OpenGL;
// otherwise inherit pixel format of window's screen
if (m_platformOpenGLContext != 0) {
@@ -666,7 +666,7 @@ void QQnxWindow::gainedFocus()
QWindowSystemInterface::handleWindowActivated(window());
}
-#ifndef QT_NO_OPENGL
+#if !defined(QT_NO_OPENGL)
void QQnxWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext)
{
// This function does not take ownership of the platform gl context.
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index ad136227e3..4a327fd54b 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -49,7 +49,7 @@
#include <QtGui/QImage>
#include <QtCore/QMutex>
-#ifndef QT_NO_OPENGL
+#if !defined(QT_NO_OPENGL)
#include <EGL/egl.h>
#endif
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
// all surfaces double buffered
#define MAX_BUFFER_COUNT 2
-#ifndef QT_NO_OPENGL
+#if !defined(QT_NO_OPENGL)
class QQnxGLContext;
#endif
class QQnxScreen;
@@ -108,7 +108,7 @@ public:
QQnxScreen *screen() const { return m_screen; }
const QList<QQnxWindow*>& children() const { return m_childWindows; }
-#ifndef QT_NO_OPENGL
+#if !defined(QT_NO_OPENGL)
void setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext);
QQnxGLContext *platformOpenGLContext() const { return m_platformOpenGLContext; }
#endif
@@ -144,7 +144,7 @@ private:
QRegion m_previousDirty;
QRegion m_scrolled;
-#ifndef QT_NO_OPENGL
+#if !defined(QT_NO_OPENGL)
QQnxGLContext *m_platformOpenGLContext;
#endif
QQnxScreen *m_screen;
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index fb08daa38e..44e715d0ce 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -645,7 +645,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locationInParent(long *x, l
QPoint topLeft = accessible->rect().topLeft();
- if (QAccessibleInterface *parentIface = accessible->parent())
+ QAccessibleInterface *parentIface = accessible->parent();
+ if (parentIface && parentIface->isValid())
topLeft -= parentIface->rect().topLeft();
*x = topLeft.x();
@@ -1596,7 +1597,7 @@ uint QWindowsIA2Accessible::uniqueID() const
if (!uid) {
QAccessibleInterface *acc = accessible;
QVector<int> indexOfNodes;
- while (acc && !acc->object()) {
+ while (acc && acc->isValid() && !acc->object()) {
QAccessibleInterface *par = acc->parent();
indexOfNodes.append(par->indexOfChild(acc));
if (acc != accessible)
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
index 752b9e7c20..79d0934ebb 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
@@ -169,7 +169,9 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
// An event has to be associated with a window,
// so find the first parent that is a widget and that has a WId
QAccessibleInterface *iface = event->accessibleInterface();
- QWindow *window = iface ? QWindowsAccessibility::windowHelper(iface) : 0;
+ if (!iface) // ### This should not happen, maybe make it an assert.
+ return;
+ QWindow *window = QWindowsAccessibility::windowHelper(iface);
delete iface;
if (!window) {
@@ -213,7 +215,7 @@ QWindow *QWindowsAccessibility::windowHelper(const QAccessibleInterface *iface)
QWindow *window = iface->window();
if (!window) {
QAccessibleInterface *acc = iface->parent();
- while (acc && !window) {
+ while (acc && acc->isValid() && !window) {
window = acc->window();
QAccessibleInterface *par = acc->parent();
delete acc;
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index bb5d5d13a7..9958615d45 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -612,7 +612,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accNavigate(long navDir, VARIA
case NAVDIR_PREVIOUS:
if (!varStart.lVal){
QAccessibleInterface *parent = accessible->parent();
- if (parent) {
+ if (parent && parent->isValid()) {
int index = parent->indexOfChild(accessible);
index += (navDir == NAVDIR_NEXT) ? 1 : -1;
if (index >= 0 && index < parent->childCount())
@@ -631,8 +631,9 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accNavigate(long navDir, VARIA
case NAVDIR_UP:
case NAVDIR_DOWN:
case NAVDIR_LEFT:
- case NAVDIR_RIGHT:
- if (QAccessibleInterface *pIface = accessible->parent()) {
+ case NAVDIR_RIGHT: {
+ QAccessibleInterface *pIface = accessible->parent();
+ if (pIface && pIface->isValid()) {
const int indexOfOurself = pIface->indexOfChild(accessible);
QRect startg = accessible->rect();
QPoint startc = startg.center();
@@ -709,6 +710,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accNavigate(long navDir, VARIA
delete pIface;
acc = candidate;
}
+ }
break;
default:
break;
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 5cc5230832..8565bf0204 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -1340,7 +1340,9 @@ static inline QString appendSuffix(const QString &fileName, const QString &filte
if (suffixPos < 0)
return fileName;
suffixPos += 3;
- int endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1);
+ int endPos = filter.indexOf(QLatin1Char(' '), suffixPos + 1);
+ if (endPos < 0)
+ endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1);
if (endPos < 0)
endPos = filter.indexOf(QLatin1Char(')'), suffixPos + 1);
if (endPos < 0)
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 6cbe3e8cf7..9b2b67619d 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -791,13 +791,16 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
m_iconSmall(0),
m_iconBig(0)
{
- if (aWindow->surfaceType() == QWindow::OpenGLSurface)
- setFlag(OpenGLSurface);
// Clear the creation context as the window can be found in QWindowsContext's map.
QWindowsContext::instance()->setWindowCreationContext(QSharedPointer<QWindowCreationContext>());
QWindowsContext::instance()->addWindow(m_data.hwnd, this);
+ const Qt::WindowType type = aWindow->type();
+ if (type == Qt::Desktop)
+ return; // No further handling for Qt::Desktop
+ if (aWindow->surfaceType() == QWindow::OpenGLSurface)
+ setFlag(OpenGLSurface);
if (aWindow->isTopLevel()) {
- switch (aWindow->type()) {
+ switch (type) {
case Qt::Window:
case Qt::Dialog:
case Qt::Sheet:
@@ -811,8 +814,13 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
}
}
#ifndef Q_OS_WINCE
- if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch)
- QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, 0);
+ if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) {
+ if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, 0)) {
+ setFlag(TouchRegistered);
+ } else {
+ qErrnoWarning("RegisterTouchWindow() failed for window '%s'.", qPrintable(aWindow->objectName()));
+ }
+ }
#endif // !Q_OS_WINCE
setWindowState(aWindow->windowState());
const qreal opacity = qt_window_private(aWindow)->opacity;
@@ -824,7 +832,7 @@ QWindowsWindow::~QWindowsWindow()
{
#ifndef Q_OS_WINCE
QWindowSystemInterface::flushWindowSystemEvents();
- if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch)
+ if (testFlag(TouchRegistered))
QWindowsContext::user32dll.unregisterTouchWindow(m_data.hwnd);
#endif // !Q_OS_WINCE
destroyWindow();
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 87397f1c1d..1148440f05 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -131,7 +131,8 @@ public:
FrameStrutEventsEnabled = 0x200,
SynchronousGeometryChangeEvent = 0x400,
WithinSetStyle = 0x800,
- WithinDestroy = 0x1000
+ WithinDestroy = 0x1000,
+ TouchRegistered = 0x2000
};
struct WindowData
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index ff40c6a9ab..3fd2ca70e3 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -490,7 +490,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0);
}
- if (cursor && cshape >= 0 && cshape < Qt::LastCursor) {
+ if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) {
const char *name = cursorNames[cshape];
xcb_xfixes_set_cursor_name(conn, cursor, strlen(name), name);
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 20d312216a..5af6a9ec9d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -186,6 +186,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_gravity(XCB_GRAVITY_STATIC)
, m_mapped(false)
, m_transparent(false)
+ , m_usingSyncProtocol(false)
, m_deferredActivation(false)
, m_embedded(false)
, m_netWmUserTimeWindow(XCB_NONE)
@@ -354,7 +355,9 @@ void QXcbWindow::create()
properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
- if (m_screen->syncRequestSupported())
+ m_usingSyncProtocol = m_screen->syncRequestSupported() && window()->surfaceType() != QSurface::OpenGLSurface;
+
+ if (m_usingSyncProtocol)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
if (window()->flags() & Qt::WindowContextHelpButtonHint)
@@ -371,7 +374,7 @@ void QXcbWindow::create()
m_syncValue.hi = 0;
m_syncValue.lo = 0;
- if (m_screen->syncRequestSupported()) {
+ if (m_usingSyncProtocol) {
m_syncCounter = xcb_generate_id(xcb_connection());
Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue));
@@ -463,7 +466,7 @@ void QXcbWindow::destroy()
if (connection()->focusWindow() == this)
connection()->setFocusWindow(0);
- if (m_syncCounter && m_screen->syncRequestSupported())
+ if (m_syncCounter && m_usingSyncProtocol)
Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
if (m_window) {
if (m_netWmUserTimeWindow) {
@@ -1824,7 +1827,7 @@ void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
void QXcbWindow::updateSyncRequestCounter()
{
- if (m_screen->syncRequestSupported() && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
+ if (m_usingSyncProtocol && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
xcb_flush(xcb_connection());
connection()->sync();
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 1810a58c7b..f4bd2d96ff 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -189,6 +189,7 @@ private:
bool m_mapped;
bool m_transparent;
+ bool m_usingSyncProtocol;
bool m_deferredActivation;
bool m_deferredExpose;
bool m_configureNotifyPending;