diff options
Diffstat (limited to 'src/gui/kernel/qguiapplication.cpp')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 176 |
1 files changed, 116 insertions, 60 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 834449fec6..137310ffbd 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1,31 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $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 The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** @@ -37,6 +44,7 @@ #include <qpa/qplatformintegrationfactory_p.h> #include "private/qevent_p.h" #include "qfont.h" +#include "qtouchdevice.h" #include <qpa/qplatformfontdatabase.h> #include <qpa/qplatformwindow.h> #include <qpa/qplatformnativeinterface.h> @@ -123,8 +131,6 @@ Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier; QPointF QGuiApplicationPrivate::lastCursorPosition(qInf(), qInf()); -Qt::MouseButtons QGuiApplicationPrivate::tabletState = Qt::NoButton; -QWindow *QGuiApplicationPrivate::tabletPressTarget = 0; QWindow *QGuiApplicationPrivate::currentMouseWindow = 0; QString QGuiApplicationPrivate::styleOverride; @@ -133,6 +139,8 @@ Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationI bool QGuiApplicationPrivate::highDpiScalingUpdated = false; +QVector<QGuiApplicationPrivate::TabletPointData> QGuiApplicationPrivate::tabletDevicePoints; + QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0; QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0; @@ -154,6 +162,7 @@ QIcon *QGuiApplicationPrivate::app_icon = 0; QString *QGuiApplicationPrivate::platform_name = 0; QString *QGuiApplicationPrivate::displayName = 0; +QString *QGuiApplicationPrivate::desktopFileName = 0; QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette @@ -190,9 +199,6 @@ bool QGuiApplicationPrivate::obey_desktop_settings = true; QInputDeviceManager *QGuiApplicationPrivate::m_inputDeviceManager = 0; -// enable the fix for QTBUG-50199; TODO remove this check in 5.7 -bool QGuiApplicationPrivate::scrollNoPhaseAllowed = false; - static qreal fontSmoothingGamma = 1.7; extern void qRegisterGuiVariant(); @@ -618,6 +624,8 @@ QGuiApplication::~QGuiApplication() QGuiApplicationPrivate::displayName = 0; delete QGuiApplicationPrivate::m_inputDeviceManager; QGuiApplicationPrivate::m_inputDeviceManager = 0; + delete QGuiApplicationPrivate::desktopFileName; + QGuiApplicationPrivate::desktopFileName = 0; } QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags) @@ -659,6 +667,34 @@ QString QGuiApplication::applicationDisplayName() } /*! + \property QGuiApplication::desktopFileName + \brief the base name of the desktop entry for this application + \since 5.7 + + This is the file name, without the full path, of the desktop entry + that represents this application according to the freedesktop desktop + entry specification. + + This property gives a precise indication of what desktop entry represents + the application and it is needed by the windowing system to retrieve + such information without resorting to imprecise heuristics. + + The latest version of the freedesktop desktop entry specification can be obtained + \l{http://standards.freedesktop.org/desktop-entry-spec/latest/}{here}. +*/ +void QGuiApplication::setDesktopFileName(const QString &name) +{ + if (!QGuiApplicationPrivate::desktopFileName) + QGuiApplicationPrivate::desktopFileName = new QString; + *QGuiApplicationPrivate::desktopFileName = name; +} + +QString QGuiApplication::desktopFileName() +{ + return QGuiApplicationPrivate::desktopFileName ? *QGuiApplicationPrivate::desktopFileName : QString(); +} + +/*! Returns the most recently shown modal window. If no modal windows are visible, this function returns zero. @@ -687,9 +723,10 @@ static void updateBlockedStatusRecursion(QWindow *window, bool shouldBeBlocked) p->blockedByModalWindow = shouldBeBlocked; QEvent e(shouldBeBlocked ? QEvent::WindowBlocked : QEvent::WindowUnblocked); QGuiApplication::sendEvent(window, &e); - foreach (QObject *c, window->children()) + for (QObject *c : window->children()) { if (c->isWindowType()) updateBlockedStatusRecursion(static_cast<QWindow *>(c), shouldBeBlocked); + } } } @@ -958,9 +995,8 @@ qreal QGuiApplication::devicePixelRatio() const } topDevicePixelRatio = 1.0; // make sure we never return 0. - foreach (QScreen *screen, QGuiApplicationPrivate::screen_list) { + for (QScreen *screen : qAsConst(QGuiApplicationPrivate::screen_list)) topDevicePixelRatio = qMax(topDevicePixelRatio, screen->devicePixelRatio()); - } return topDevicePixelRatio; } @@ -976,7 +1012,7 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos) QScreen *windowScreen = Q_NULLPTR; // Find the window on the primary virtual desktop first - foreach (QScreen *screen, primaryScreens) { + for (QScreen *screen : primaryScreens) { if (screen->geometry().contains(pos)) { windowScreen = screen; break; @@ -988,7 +1024,7 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos) // may repeat. Find only when there is more than one virtual desktop. if (!windowScreen && screens.count() != primaryScreens.count()) { for (int i = 1; i < screens.size(); ++i) { - QScreen *screen = screens[i]; + QScreen *screen = screens.at(i); if (screen->geometry().contains(pos)) { windowScreen = screen; break; @@ -1056,9 +1092,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform // Create the platform integration. QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath); - if (QGuiApplicationPrivate::platform_integration) { - QGuiApplicationPrivate::platform_name = new QString(name); - } else { + if (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) { QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath); QString fatalMessage @@ -1078,6 +1112,8 @@ static void init_platform(const QString &pluginArgument, const QString &platform return; } + QGuiApplicationPrivate::platform_name = new QString(name); + // Many platforms have created QScreens at this point. Finish initializing // QHighDpiScaling to be prepared for early calls to qt_defaultDpi(). if (QGuiApplication::primaryScreen()) { @@ -1095,7 +1131,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform // 2) Ask the platform integration for a list of theme names themeNames += QGuiApplicationPrivate::platform_integration->themeNames(); // 3) Look for a theme plugin. - foreach (const QString &themeName, themeNames) { + for (const QString &themeName : qAsConst(themeNames)) { QGuiApplicationPrivate::platform_theme = QPlatformThemeFactory::create(themeName, platformPluginPath); if (QGuiApplicationPrivate::platform_theme) break; @@ -1104,7 +1140,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform // 4) If no theme plugin was found ask the platform integration to // create a theme if (!QGuiApplicationPrivate::platform_theme) { - foreach (const QString &themeName, themeNames) { + for (const QString &themeName : qAsConst(themeNames)) { QGuiApplicationPrivate::platform_theme = QGuiApplicationPrivate::platform_integration->createPlatformTheme(themeName); if (QGuiApplicationPrivate::platform_theme) break; @@ -1121,7 +1157,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform // boolean 'foo' or strings: 'foo=bar' if (!arguments.isEmpty()) { if (QObject *nativeInterface = QGuiApplicationPrivate::platform_integration->nativeInterface()) { - foreach (const QString &argument, arguments) { + for (const QString &argument : qAsConst(arguments)) { const int equalsPos = argument.indexOf(QLatin1Char('=')); const QByteArray name = equalsPos != -1 ? argument.left(equalsPos).toUtf8() : argument.toUtf8(); @@ -1330,9 +1366,9 @@ void QGuiApplicationPrivate::init() } else if (strcmp(arg, "-testability") == 0) { loadTestability = true; } else if (strncmp(arg, "-style=", 7) == 0) { - s = QString::fromLocal8Bit(arg + 7).toLower(); + s = QString::fromLocal8Bit(arg + 7); } else if (strcmp(arg, "-style") == 0 && i < argc - 1) { - s = QString::fromLocal8Bit(argv[++i]).toLower(); + s = QString::fromLocal8Bit(argv[++i]); } else { argv[j++] = argv[i]; } @@ -1348,10 +1384,8 @@ void QGuiApplicationPrivate::init() // Load environment exported generic plugins QByteArray envPlugins = qgetenv("QT_QPA_GENERIC_PLUGINS"); - if (!envPlugins.isEmpty()) { - foreach (const QByteArray &plugin, envPlugins.split(',')) - pluginList << plugin; - } + if (!envPlugins.isEmpty()) + pluginList += envPlugins.split(','); if (platform_integration == 0) createPlatformIntegration(); @@ -1403,16 +1437,16 @@ void QGuiApplicationPrivate::init() if (loadTestability) { QLibrary testLib(QStringLiteral("qttestability")); - if (testLib.load()) { + if (Q_UNLIKELY(!testLib.load())) { + qCritical() << "Library qttestability load failed:" << testLib.errorString(); + } else { typedef void (*TasInitialize)(void); TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init"); - if (initFunction) { - initFunction(); + if (Q_UNLIKELY(!initFunction)) { + qCritical("Library qttestability resolve failed!"); } else { - qCritical() << "Library qttestability resolve failed!"; + initFunction(); } - } else { - qCritical() << "Library qttestability load failed:" << testLib.errorString(); } } #else @@ -1421,8 +1455,6 @@ void QGuiApplicationPrivate::init() if (layout_direction == Qt::LayoutDirectionAuto || force_reverse) QGuiApplication::setLayoutDirection(qt_detectRTLLanguage() ? Qt::RightToLeft : Qt::LeftToRight); - - scrollNoPhaseAllowed = qEnvironmentVariableIsSet("QT_ENABLE_MOUSE_WHEEL_TRACKING"); } extern void qt_cleanupFontDatabase(); @@ -1569,7 +1601,7 @@ QFunctionPointer QGuiApplication::platformFunction(const QByteArray &function) { QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); if (!pi) { - qWarning() << "QGuiApplication::platformFunction(): Must construct a QGuiApplication before accessing a platform function"; + qWarning("QGuiApplication::platformFunction(): Must construct a QGuiApplication before accessing a platform function"); return Q_NULLPTR; } @@ -1948,7 +1980,8 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh return; } - QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers, e->phase, e->source); + QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, + buttons, e->modifiers, e->phase, e->source, e->inverted); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &ev); #endif /* ifndef QT_NO_WHEELEVENT */ @@ -1961,7 +1994,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE QWindow *window = e->window.data(); modifier_buttons = e->modifiers; if (e->nullWindow() -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) +#if defined(Q_OS_ANDROID) || e->key == Qt::Key_Back || e->key == Qt::Key_Menu #endif ) { @@ -1987,7 +2020,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE if (window && !window->d_func()->blockedByModalWindow) QGuiApplication::sendSpontaneousEvent(window, &ev); -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) +#if defined(Q_OS_ANDROID) else ev.setAccepted(false); @@ -2204,12 +2237,26 @@ void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate: QGuiApplication::sendSpontaneousEvent(qApp, &event); } +QGuiApplicationPrivate::TabletPointData &QGuiApplicationPrivate::tabletDevicePoint(qint64 deviceId) +{ + for (int i = 0; i < tabletDevicePoints.size(); ++i) { + TabletPointData &pointData = tabletDevicePoints[i]; + if (pointData.deviceId == deviceId) + return pointData; + } + + tabletDevicePoints.append(TabletPointData(deviceId)); + return tabletDevicePoints.last(); +} + void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e) { #ifndef QT_NO_TABLETEVENT + TabletPointData &pointData = tabletDevicePoint(e->uid); + QEvent::Type type = QEvent::TabletMove; - if (e->buttons != tabletState) - type = (e->buttons > tabletState) ? QEvent::TabletPress : QEvent::TabletRelease; + if (e->buttons != pointData.state) + type = (e->buttons > pointData.state) ? QEvent::TabletPress : QEvent::TabletRelease; QWindow *window = e->window.data(); modifier_buttons = e->modifiers; @@ -2225,14 +2272,14 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T } if (!window) return; - tabletPressTarget = window; + pointData.target = window; } else { if (e->nullWindow()) { - window = tabletPressTarget; + window = pointData.target; localValid = false; } if (type == QEvent::TabletRelease) - tabletPressTarget = 0; + pointData.target = Q_NULLPTR; if (!window) return; } @@ -2241,7 +2288,7 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T QPointF delta = e->global - e->global.toPoint(); local = window->mapFromGlobal(e->global.toPoint()) + delta; } - Qt::MouseButtons stateChange = e->buttons ^ tabletState; + Qt::MouseButtons stateChange = e->buttons ^ pointData.state; Qt::MouseButton button = Qt::NoButton; for (int check = Qt::LeftButton; check <= int(Qt::MaxMouseButton); check = check << 1) { if (check & stateChange) { @@ -2253,9 +2300,17 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T e->device, e->pointerType, e->pressure, e->xTilt, e->yTilt, e->tangentialPressure, e->rotation, e->z, e->modifiers, e->uid, button, e->buttons); + ev.setAccepted(false); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &ev); - tabletState = e->buttons; + pointData.state = e->buttons; + if (!ev.isAccepted() && !QWindowSystemInterfacePrivate::TabletEvent::platformSynthesizesMouse + && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents)) { + QWindowSystemInterfacePrivate::MouseEvent fake(window, e->timestamp, e->local, e->global, + e->buttons, e->modifiers, Qt::MouseEventSynthesizedByQt); + fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; + processMouseEvent(&fake); + } #else Q_UNUSED(e) #endif @@ -2267,7 +2322,7 @@ void QGuiApplicationPrivate::processTabletEnterProximityEvent(QWindowSystemInter QTabletEvent ev(QEvent::TabletEnterProximity, QPointF(), QPointF(), e->device, e->pointerType, 0, 0, 0, 0, 0, 0, - Qt::NoModifier, e->uid, Qt::NoButton, tabletState); + Qt::NoModifier, e->uid, Qt::NoButton, tabletDevicePoint(e->uid).state); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev); #else @@ -2281,7 +2336,7 @@ void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInter QTabletEvent ev(QEvent::TabletLeaveProximity, QPointF(), QPointF(), e->device, e->pointerType, 0, 0, 0, 0, 0, 0, - Qt::NoModifier, e->uid, Qt::NoButton, tabletState); + Qt::NoModifier, e->uid, Qt::NoButton, tabletDevicePoint(e->uid).state); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev); #else @@ -2562,7 +2617,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To if (b == Qt::NoButton) self->synthesizedMousePoints.clear(); - QList<QTouchEvent::TouchPoint> touchPoints = touchEvent.touchPoints(); + const QList<QTouchEvent::TouchPoint> &touchPoints = touchEvent.touchPoints(); if (eventType == QEvent::TouchBegin) m_fakeMouseSourcePointId = touchPoints.first().id(); @@ -2672,7 +2727,8 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate: emit s->availableGeometryChanged(s->availableGeometry()); if (geometryChanged || availableGeometryChanged) { - foreach (QScreen* sibling, s->virtualSiblings()) + const auto siblings = s->virtualSiblings(); + for (QScreen* sibling : siblings) emit sibling->virtualGeometryChanged(sibling->virtualGeometry()); } } @@ -3622,7 +3678,7 @@ void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object) emit q->focusObjectChanged(object); } -enum { +enum MouseMasks { MouseCapsMask = 0xFF, MouseSourceMaskDst = 0xFF00, MouseSourceMaskSrc = MouseCapsMask, |