diff options
Diffstat (limited to 'src/platformsupport')
23 files changed, 603 insertions, 182 deletions
diff --git a/src/platformsupport/cglconvenience/cglconvenience.mm b/src/platformsupport/cglconvenience/cglconvenience.mm index 6b0a91e13f..b20f324442 100644 --- a/src/platformsupport/cglconvenience/cglconvenience.mm +++ b/src/platformsupport/cglconvenience/cglconvenience.mm @@ -34,7 +34,7 @@ #include "cglconvenience_p.h" #include <QtCore/qglobal.h> #include <QtCore/private/qcore_mac_p.h> -#include <Cocoa/Cocoa.h> +#include <AppKit/AppKit.h> #include <QVector> void (*qcgl_getProcAddress(const QByteArray &procName))() diff --git a/src/platformsupport/cglconvenience/cglconvenience.pri b/src/platformsupport/cglconvenience/cglconvenience.pri index 0e86ddb208..1de38bbd08 100644 --- a/src/platformsupport/cglconvenience/cglconvenience.pri +++ b/src/platformsupport/cglconvenience/cglconvenience.pri @@ -1,4 +1,4 @@ -mac:!ios { +osx { INCLUDEPATH += $$PWD HEADERS += \ @@ -7,5 +7,5 @@ mac:!ios { OBJECTIVE_SOURCES += \ $$PWD/cglconvenience.mm - LIBS_PRIVATE += -framework Cocoa -framework OpenGL + LIBS_PRIVATE += -framework AppKit -framework OpenGL } diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index ffa548bf83..5fec32c650 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -32,10 +32,13 @@ ****************************************************************************/ #include <QtCore/qsystemdetection.h> + +#if defined(Q_OS_OSX) +#import <AppKit/AppKit.h> +#endif + #if defined(Q_OS_IOS) #import <UIKit/UIKit.h> -#elif defined(Q_OS_OSX) -#import <Cocoa/Cocoa.h> #endif #include "qmacmime_p.h" diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp index 3aab785b34..4bf7508b2f 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp @@ -56,6 +56,12 @@ #ifndef ABS_CNT #define ABS_CNT (ABS_MAX+1) #endif +#ifndef ABS_MT_POSITION_X +#define ABS_MT_POSITION_X 0x35 +#endif +#ifndef ABS_MT_POSITION_Y +#define ABS_MT_POSITION_Y 0x36 +#endif #define LONG_BITS (sizeof(long) * 8 ) #define LONG_FIELD_SIZE(bits) ((bits / LONG_BITS) + 1) @@ -113,67 +119,73 @@ QStringList QDeviceDiscoveryStatic::scanConnectedDevices() bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device) { - bool ret = false; int fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); - if (!fd) { + if (Q_UNLIKELY(fd == -1)) { qWarning() << "Device discovery cannot open device" << device; return false; } + qCDebug(lcDD) << "doing static device discovery for " << device; + + if ((m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX))) { + QT_CLOSE(fd); + return true; + } + + long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)]; long bitsKey[LONG_FIELD_SIZE(KEY_CNT)]; - if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitsKey)), bitsKey) >= 0 ) { - if (!ret && (m_types & Device_Keyboard)) { - if (testBit(KEY_Q, bitsKey)) { - qCDebug(lcDD) << "Found keyboard at" << device; - ret = true; - } - } + long bitsRel[LONG_FIELD_SIZE(REL_CNT)]; + memset(bitsAbs, 0, sizeof(bitsAbs)); + memset(bitsKey, 0, sizeof(bitsKey)); + memset(bitsRel, 0, sizeof(bitsRel)); - if (!ret && (m_types & Device_Mouse)) { - long bitsRel[LONG_FIELD_SIZE(REL_CNT)]; - if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitsRel)), bitsRel) >= 0 ) { - if (testBit(REL_X, bitsRel) && testBit(REL_Y, bitsRel) && testBit(BTN_MOUSE, bitsKey)) { - qCDebug(lcDD) << "Found mouse at" << device; - ret = true; - } - } + ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs); + ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitsKey)), bitsKey); + ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitsRel)), bitsRel); + + QT_CLOSE(fd); + + if ((m_types & Device_Keyboard)) { + if (testBit(KEY_Q, bitsKey)) { + qCDebug(lcDD) << "Found keyboard at" << device; + return true; } + } - if (!ret && (m_types & (Device_Touchpad | Device_Touchscreen))) { - long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)]; - if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs) >= 0 ) { - if (testBit(ABS_X, bitsAbs) && testBit(ABS_Y, bitsAbs)) { - if ((m_types & Device_Touchpad) && testBit(BTN_TOOL_FINGER, bitsKey)) { - qCDebug(lcDD) << "Found touchpad at" << device; - ret = true; - } else if ((m_types & Device_Touchscreen) && testBit(BTN_TOUCH, bitsKey)) { - qCDebug(lcDD) << "Found touchscreen at" << device; - ret = true; - } else if ((m_types & Device_Tablet) && (testBit(BTN_STYLUS, bitsKey) || testBit(BTN_TOOL_PEN, bitsKey))) { - qCDebug(lcDD) << "Found tablet at" << device; - ret = true; - } - } - } + if ((m_types & Device_Mouse)) { + if (testBit(REL_X, bitsRel) && testBit(REL_Y, bitsRel) && testBit(BTN_MOUSE, bitsKey)) { + qCDebug(lcDD) << "Found mouse at" << device; + return true; } + } - if (!ret && (m_types & Device_Joystick)) { - long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)]; - if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs) >= 0 ) { - if ((m_types & Device_Joystick) - && (testBit(BTN_A, bitsKey) || testBit(BTN_TRIGGER, bitsKey) || testBit(ABS_RX, bitsAbs))) { - qCDebug(lcDD) << "Found joystick/gamepad at" << device; - ret = true; - } + if ((m_types & (Device_Touchpad | Device_Touchscreen))) { + if (testBit(ABS_X, bitsAbs) && testBit(ABS_Y, bitsAbs)) { + if ((m_types & Device_Touchpad) && testBit(BTN_TOOL_FINGER, bitsKey)) { + qCDebug(lcDD) << "Found touchpad at" << device; + return true; + } else if ((m_types & Device_Touchscreen) && testBit(BTN_TOUCH, bitsKey)) { + qCDebug(lcDD) << "Found touchscreen at" << device; + return true; + } else if ((m_types & Device_Tablet) && (testBit(BTN_STYLUS, bitsKey) || testBit(BTN_TOOL_PEN, bitsKey))) { + qCDebug(lcDD) << "Found tablet at" << device; + return true; } + } else if (testBit(ABS_MT_POSITION_X, bitsAbs) && + testBit(ABS_MT_POSITION_Y, bitsAbs)) { + qCDebug(lcDD) << "Found new-style touchscreen at" << device; + return true; } } - if (!ret && (m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX))) - ret = true; + if ((m_types & Device_Joystick)) { + if (testBit(BTN_A, bitsKey) || testBit(BTN_TRIGGER, bitsKey) || testBit(ABS_RX, bitsAbs)) { + qCDebug(lcDD) << "Found joystick/gamepad at" << device; + return true; + } + } - QT_CLOSE(fd); - return ret; + return false; } QT_END_NAMESPACE diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp index f285e61a9f..334eb51a86 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp @@ -185,11 +185,11 @@ void QDeviceDiscoveryUDev::handleUDevNotification() // if we cannot determine a type, walk up the device tree if (!checkDeviceType(dev)) { // does not increase the refcount - dev = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, 0); - if (!dev) + struct udev_device *parent_dev = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, 0); + if (!parent_dev) goto cleanup; - if (!checkDeviceType(dev)) + if (!checkDeviceType(parent_dev)) goto cleanup; } diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index a5fe88871d..02217a7179 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -36,6 +36,7 @@ #include <QtCore/QList> #include <QtCore/QElapsedTimer> +#include <QtCore/QFile> #include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformscreen.h> diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 0af779097c..a87443cc85 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -35,8 +35,8 @@ #include <sys/param.h> -#if defined(Q_OS_MACX) -#import <Cocoa/Cocoa.h> +#if defined(Q_OS_OSX) +#import <AppKit/AppKit.h> #import <IOKit/graphics/IOGraphicsLib.h> #elif defined(Q_OS_IOS) #import <UIKit/UIFont.h> diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 732aead62a..be1696dfe8 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -215,6 +215,8 @@ void QCoreTextFontEngine::init() Q_ASSERT((void *)(&ctfont + 1) == (void *)&cgFont); faceData.user_data = &ctfont; faceData.get_font_table = ct_getSfntTable; + + kerningPairsLoaded = false; } glyph_t QCoreTextFontEngine::glyphIndex(uint ucs4) const @@ -788,4 +790,17 @@ QFontEngine::Properties QCoreTextFontEngine::properties() const return result; } +void QCoreTextFontEngine::doKerning(QGlyphLayout *g, ShaperFlags flags) const +{ + if (!kerningPairsLoaded) { + kerningPairsLoaded = true; + qreal emSquare = CTFontGetUnitsPerEm(ctfont); + qreal scale = emSquare / CTFontGetSize(ctfont); + + const_cast<QCoreTextFontEngine *>(this)->loadKerningPairs(QFixed::fromReal(scale)); + } + + QFontEngine::doKerning(g, flags); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 1c33ae7d84..c22d1ddc0a 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -97,6 +97,7 @@ public: glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) Q_DECL_OVERRIDE; QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE; QFixed emSquareSize() const Q_DECL_OVERRIDE; + void doKerning(QGlyphLayout *g, ShaperFlags flags) const Q_DECL_OVERRIDE; bool supportsTransformation(const QTransform &transform) const Q_DECL_OVERRIDE; @@ -134,6 +135,7 @@ private: CGAffineTransform transform; QFixed avgCharWidth; QFontEngine::FaceId face_id; + mutable bool kerningPairsLoaded; }; CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef); diff --git a/src/platformsupport/graphics/graphics.pri b/src/platformsupport/graphics/graphics.pri new file mode 100644 index 0000000000..43062682aa --- /dev/null +++ b/src/platformsupport/graphics/graphics.pri @@ -0,0 +1,2 @@ +HEADERS += $$PWD/qrasterbackingstore_p.h +SOURCES += $$PWD/qrasterbackingstore.cpp diff --git a/src/platformsupport/graphics/qrasterbackingstore.cpp b/src/platformsupport/graphics/qrasterbackingstore.cpp new file mode 100644 index 0000000000..a64a4cfa40 --- /dev/null +++ b/src/platformsupport/graphics/qrasterbackingstore.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qrasterbackingstore_p.h" + +#include <QtGui/qpainter.h> + +QT_BEGIN_NAMESPACE + +QRasterBackingStore::QRasterBackingStore(QWindow *window) + : QPlatformBackingStore(window) +{ +} + +QRasterBackingStore::~QRasterBackingStore() +{ +} + +void QRasterBackingStore::resize(const QSize &size, const QRegion &staticContents) +{ + Q_UNUSED(staticContents); + + int windowDevicePixelRatio = window()->devicePixelRatio(); + QSize effectiveBufferSize = size * windowDevicePixelRatio; + + if (m_image.size() == effectiveBufferSize) + return; + + QImage::Format format = window()->format().hasAlpha() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + m_image = QImage(effectiveBufferSize, format); + m_image.setDevicePixelRatio(windowDevicePixelRatio); + if (format == QImage::Format_ARGB32_Premultiplied) + m_image.fill(Qt::transparent); +} + +QPaintDevice *QRasterBackingStore::paintDevice() +{ + return &m_image; +} + +QImage QRasterBackingStore::toImage() const +{ + return m_image; +} + +bool QRasterBackingStore::scroll(const QRegion ®ion, int dx, int dy) +{ + if (window()->surfaceType() != QSurface::RasterSurface) + return false; + + extern void qt_scrollRectInImage(QImage &, const QRect &, const QPoint &); + + const qreal devicePixelRatio = m_image.devicePixelRatio(); + const QPoint delta(dx * devicePixelRatio, dy * devicePixelRatio); + + foreach (const QRect &rect, region.rects()) + qt_scrollRectInImage(m_image, QRect(rect.topLeft() * devicePixelRatio, rect.size() * devicePixelRatio), delta); + + return true; +} + +void QRasterBackingStore::beginPaint(const QRegion ®ion) +{ + if (!m_image.hasAlphaChannel()) + return; + + QPainter painter(&m_image); + painter.setCompositionMode(QPainter::CompositionMode_Source); + const QColor blank = Qt::transparent; + foreach (const QRect &rect, region.rects()) + painter.fillRect(rect, blank); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/graphics/qrasterbackingstore_p.h b/src/platformsupport/graphics/qrasterbackingstore_p.h new file mode 100644 index 0000000000..314a6e6e79 --- /dev/null +++ b/src/platformsupport/graphics/qrasterbackingstore_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QRASTERBACKINGSTORE_P_H +#define QRASTERBACKINGSTORE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qpa/qplatformbackingstore.h> + + +QT_BEGIN_NAMESPACE + +class QRasterBackingStore : public QPlatformBackingStore +{ +public: + QRasterBackingStore(QWindow *window); + ~QRasterBackingStore(); + + QPaintDevice *paintDevice() Q_DECL_OVERRIDE; + QImage toImage() const Q_DECL_OVERRIDE; + void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE; + bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; + void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; + +protected: + QImage m_image; +}; + +QT_END_NAMESPACE + +#endif // QRASTERBACKINGSTORE_P_H diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index 06751de0ef..d467a62abd 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -35,6 +35,7 @@ #include <qplatformdefs.h> +#include <QFile> #include <QSocketNotifier> #include <QStringList> #include <QCoreApplication> diff --git a/src/platformsupport/input/evdevtablet/evdevtablet.pri b/src/platformsupport/input/evdevtablet/evdevtablet.pri index 5ace0df61d..fb9489353c 100644 --- a/src/platformsupport/input/evdevtablet/evdevtablet.pri +++ b/src/platformsupport/input/evdevtablet/evdevtablet.pri @@ -1,8 +1,10 @@ HEADERS += \ - $$PWD/qevdevtablet_p.h + $$PWD/qevdevtablethandler_p.h \ + $$PWD/qevdevtabletmanager_p.h SOURCES += \ - $$PWD/qevdevtablet.cpp + $$PWD/qevdevtablethandler.cpp \ + $$PWD/qevdevtabletmanager.cpp contains(QT_CONFIG, libudev) { LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp b/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp index c6f952c64d..aa87340112 100644 --- a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp +++ b/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp @@ -31,14 +31,14 @@ ** ****************************************************************************/ -#include "qevdevtablet_p.h" -#include <qpa/qwindowsysteminterface.h> +#include "qevdevtablethandler_p.h" + #include <QStringList> #include <QSocketNotifier> #include <QGuiApplication> #include <QLoggingCategory> #include <QtCore/private/qcore_unix_p.h> -#include <QtPlatformSupport/private/qdevicediscovery_p.h> +#include <qpa/qwindowsysteminterface.h> #include <linux/input.h> QT_BEGIN_NAMESPACE @@ -49,16 +49,11 @@ class QEvdevTabletData { public: QEvdevTabletData(QEvdevTabletHandler *q_ptr); - bool queryLimits(); - void testGrab(); + void processInputEvent(input_event *ev); - void reportProximityEnter(); - void reportProximityLeave(); void report(); QEvdevTabletHandler *q; - QSocketNotifier *notifier; - int fd; int lastEventType; QString devName; struct { @@ -73,57 +68,13 @@ public: }; QEvdevTabletData::QEvdevTabletData(QEvdevTabletHandler *q_ptr) - : q(q_ptr), notifier(0), fd(-1), lastEventType(0) + : q(q_ptr), lastEventType(0) { memset(&minValues, 0, sizeof(minValues)); memset(&maxValues, 0, sizeof(maxValues)); memset(&state, 0, sizeof(state)); } -bool QEvdevTabletData::queryLimits() -{ - bool ok = true; - input_absinfo absInfo; - memset(&absInfo, 0, sizeof(input_absinfo)); - ok &= ioctl(fd, EVIOCGABS(ABS_X), &absInfo) >= 0; - if (ok) { - minValues.x = absInfo.minimum; - maxValues.x = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: min X: %d max X: %d", minValues.x, maxValues.x); - } - ok &= ioctl(fd, EVIOCGABS(ABS_Y), &absInfo) >= 0; - if (ok) { - minValues.y = absInfo.minimum; - maxValues.y = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: min Y: %d max Y: %d", minValues.y, maxValues.y); - } - if (ioctl(fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { - minValues.p = absInfo.minimum; - maxValues.p = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: min pressure: %d max pressure: %d", minValues.p, maxValues.p); - } - if (ioctl(fd, EVIOCGABS(ABS_DISTANCE), &absInfo) >= 0) { - minValues.d = absInfo.minimum; - maxValues.d = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: min distance: %d max distance: %d", minValues.d, maxValues.d); - } - char name[128]; - if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { - devName = QString::fromLocal8Bit(name); - qCDebug(qLcEvdevTablet, "evdevtablet: device name: %s", name); - } - return ok; -} - -void QEvdevTabletData::testGrab() -{ - bool grabSuccess = !ioctl(fd, EVIOCGRAB, (void *) 1); - if (grabSuccess) - ioctl(fd, EVIOCGRAB, (void *) 0); - else - qWarning("evdevtablet: ERROR: The device is grabbed by another process. No events will be read."); -} - void QEvdevTabletData::processInputEvent(input_event *ev) { if (ev->type == EV_ABS) { @@ -167,20 +118,10 @@ void QEvdevTabletData::processInputEvent(input_event *ev) lastEventType = ev->type; } -void QEvdevTabletData::reportProximityEnter() -{ - QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, 1); -} - -void QEvdevTabletData::reportProximityLeave() -{ - QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, 1); -} - void QEvdevTabletData::report() { if (!state.lastReportTool && state.tool) - reportProximityEnter(); + QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId()); qreal nx = (state.x - minValues.x) / qreal(maxValues.x - minValues.x); qreal ny = (state.y - minValues.y) / qreal(maxValues.y - minValues.y); @@ -194,16 +135,17 @@ void QEvdevTabletData::report() pointer = state.lastReportTool; } - qreal pressure = (state.p - minValues.p) / qreal(maxValues.p - minValues.p); + int pressureRange = maxValues.p - minValues.p; + qreal pressure = pressureRange ? (state.p - minValues.p) / qreal(pressureRange) : qreal(1); if (state.down || state.lastReportDown) { QWindowSystemInterface::handleTabletEvent(0, state.down, QPointF(), globalPos, QTabletEvent::Stylus, pointer, - pressure, 0, 0, 0, 0, 0, 1, qGuiApp->keyboardModifiers()); + pressure, 0, 0, 0, 0, 0, q->deviceId(), qGuiApp->keyboardModifiers()); } if (state.lastReportTool && !state.tool) - reportProximityLeave(); + QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId()); state.lastReportDown = state.down; state.lastReportTool = state.tool; @@ -211,69 +153,104 @@ void QEvdevTabletData::report() } -QEvdevTabletHandler::QEvdevTabletHandler(const QString &spec, QObject *parent) - : QObject(parent), d(0) +QEvdevTabletHandler::QEvdevTabletHandler(const QString &device, const QString &spec, QObject *parent) + : QObject(parent), m_fd(-1), m_device(device), m_notifier(0), d(0) { + Q_UNUSED(spec) + setObjectName(QLatin1String("Evdev Tablet Handler")); - d = new QEvdevTabletData(this); - QString dev; - QStringList args = spec.split(QLatin1Char(':')); - for (int i = 0; i < args.count(); ++i) { - if (args.at(i).startsWith(QLatin1String("/dev/"))) { - dev = args.at(i); - break; - } - } - if (dev.isEmpty()) { - QScopedPointer<QDeviceDiscovery> deviceDiscovery( - QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this)); - if (deviceDiscovery) { - QStringList devices = deviceDiscovery->scanConnectedDevices(); - if (!devices.isEmpty()) - dev = devices.at(0); - } - } - if (!dev.isEmpty()) { - qCDebug(qLcEvdevTablet, "evdevtablet: using %s", qPrintable(dev)); - d->fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); - if (d->fd >= 0) { - d->testGrab(); - if (d->queryLimits()) { - d->notifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, this); - connect(d->notifier, SIGNAL(activated(int)), this, SLOT(readData())); - } - } else { - qErrnoWarning(errno, "evdevtablet: Cannot open input device"); - } + + qCDebug(qLcEvdevTablet, "evdevtablet: using %s", qPrintable(device)); + + m_fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); + if (m_fd < 0) { + qErrnoWarning(errno, "evdevtablet: Cannot open input device %s", qPrintable(device)); + return; } + + bool grabSuccess = !ioctl(m_fd, EVIOCGRAB, (void *) 1); + if (grabSuccess) + ioctl(m_fd, EVIOCGRAB, (void *) 0); + else + qWarning("evdevtablet: %s: The device is grabbed by another process. No events will be read.", qPrintable(device)); + + d = new QEvdevTabletData(this); + if (!queryLimits()) + qWarning("evdevtablet: %s: Unset or invalid ABS limits. Behavior will be unspecified.", qPrintable(device)); + + m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(m_notifier, &QSocketNotifier::activated, this, &QEvdevTabletHandler::readData); } QEvdevTabletHandler::~QEvdevTabletHandler() { - delete d->notifier; - if (d->fd >= 0) - QT_CLOSE(d->fd); + if (m_fd >= 0) + QT_CLOSE(m_fd); delete d; } +qint64 QEvdevTabletHandler::deviceId() const +{ + return m_fd; +} + +bool QEvdevTabletHandler::queryLimits() +{ + bool ok = true; + input_absinfo absInfo; + memset(&absInfo, 0, sizeof(input_absinfo)); + ok &= ioctl(m_fd, EVIOCGABS(ABS_X), &absInfo) >= 0; + if (ok) { + d->minValues.x = absInfo.minimum; + d->maxValues.x = absInfo.maximum; + qCDebug(qLcEvdevTablet, "evdevtablet: %s: min X: %d max X: %d", qPrintable(m_device), + d->minValues.x, d->maxValues.x); + } + ok &= ioctl(m_fd, EVIOCGABS(ABS_Y), &absInfo) >= 0; + if (ok) { + d->minValues.y = absInfo.minimum; + d->maxValues.y = absInfo.maximum; + qCDebug(qLcEvdevTablet, "evdevtablet: %s: min Y: %d max Y: %d", qPrintable(m_device), + d->minValues.y, d->maxValues.y); + } + if (ioctl(m_fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { + d->minValues.p = absInfo.minimum; + d->maxValues.p = absInfo.maximum; + qCDebug(qLcEvdevTablet, "evdevtablet: %s: min pressure: %d max pressure: %d", qPrintable(m_device), + d->minValues.p, d->maxValues.p); + } + if (ioctl(m_fd, EVIOCGABS(ABS_DISTANCE), &absInfo) >= 0) { + d->minValues.d = absInfo.minimum; + d->maxValues.d = absInfo.maximum; + qCDebug(qLcEvdevTablet, "evdevtablet: %s: min distance: %d max distance: %d", qPrintable(m_device), + d->minValues.d, d->maxValues.d); + } + char name[128]; + if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { + d->devName = QString::fromLocal8Bit(name); + qCDebug(qLcEvdevTablet, "evdevtablet: %s: device name: %s", qPrintable(m_device), name); + } + return ok; +} + void QEvdevTabletHandler::readData() { static input_event buffer[32]; int n = 0; for (; ;) { - int result = QT_READ(d->fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n); + int result = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n); if (!result) { - qWarning("evdevtablet: Got EOF from input device"); + qWarning("evdevtablet: %s: Got EOF from input device", qPrintable(m_device)); return; } else if (result < 0) { if (errno != EINTR && errno != EAGAIN) { - qErrnoWarning(errno, "evdevtablet: Could not read from input device"); + qErrnoWarning(errno, "evdevtablet: %s: Could not read from input device", qPrintable(m_device)); if (errno == ENODEV) { // device got disconnected -> stop reading - delete d->notifier; - d->notifier = 0; - QT_CLOSE(d->fd); - d->fd = -1; + delete m_notifier; + m_notifier = 0; + QT_CLOSE(m_fd); + m_fd = -1; } return; } @@ -291,8 +268,8 @@ void QEvdevTabletHandler::readData() } -QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &spec, QObject *parent) - : QDaemonThread(parent), m_spec(spec), m_handler(0) +QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &device, const QString &spec, QObject *parent) + : QDaemonThread(parent), m_device(device), m_spec(spec), m_handler(0) { start(); } @@ -305,7 +282,7 @@ QEvdevTabletHandlerThread::~QEvdevTabletHandlerThread() void QEvdevTabletHandlerThread::run() { - m_handler = new QEvdevTabletHandler(m_spec); + m_handler = new QEvdevTabletHandler(m_device, m_spec); exec(); delete m_handler; m_handler = 0; diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h b/src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h index f546f9a88a..4a9b2bab34 100644 --- a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h +++ b/src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h @@ -31,8 +31,8 @@ ** ****************************************************************************/ -#ifndef QEVDEVTABLET_P_H -#define QEVDEVTABLET_P_H +#ifndef QEVDEVTABLETHANDLER_P_H +#define QEVDEVTABLETHANDLER_P_H // // W A R N I N G @@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE +class QSocketNotifier; class QEvdevTabletData; class QEvdevTabletHandler : public QObject @@ -59,29 +60,37 @@ class QEvdevTabletHandler : public QObject Q_OBJECT public: - explicit QEvdevTabletHandler(const QString &spec = QString(), QObject *parent = 0); + explicit QEvdevTabletHandler(const QString &device, const QString &spec = QString(), QObject *parent = 0); ~QEvdevTabletHandler(); + qint64 deviceId() const; + private slots: void readData(); private: + bool queryLimits(); + + int m_fd; + QString m_device; + QSocketNotifier *m_notifier; QEvdevTabletData *d; }; class QEvdevTabletHandlerThread : public QDaemonThread { public: - explicit QEvdevTabletHandlerThread(const QString &spec, QObject *parent = 0); + explicit QEvdevTabletHandlerThread(const QString &device, const QString &spec, QObject *parent = 0); ~QEvdevTabletHandlerThread(); void run() Q_DECL_OVERRIDE; QEvdevTabletHandler *handler() { return m_handler; } private: + QString m_device; QString m_spec; QEvdevTabletHandler *m_handler; }; QT_END_NAMESPACE -#endif // QEVDEVTABLET_P_H +#endif // QEVDEVTABLETHANDLER_P_H diff --git a/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp b/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp new file mode 100644 index 0000000000..05fd6e655c --- /dev/null +++ b/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qevdevtabletmanager_p.h" +#include "qevdevtablethandler_p.h" + +#include <QStringList> +#include <QGuiApplication> +#include <QLoggingCategory> +#include <QtPlatformSupport/private/qdevicediscovery_p.h> +#include <private/qguiapplication_p.h> +#include <private/qinputdevicemanager_p_p.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcEvdevTablet) + +QEvdevTabletManager::QEvdevTabletManager(const QString &key, const QString &specification, QObject *parent) + : QObject(parent) +{ + Q_UNUSED(key); + + if (qEnvironmentVariableIsSet("QT_QPA_EVDEV_DEBUG")) + const_cast<QLoggingCategory &>(qLcEvdevTablet()).setEnabled(QtDebugMsg, true); + + QString spec = QString::fromLocal8Bit(qgetenv("QT_QPA_EVDEV_TABLET_PARAMETERS")); + + if (spec.isEmpty()) + spec = specification; + + QStringList args = spec.split(QLatin1Char(':')); + QStringList devices; + + foreach (const QString &arg, args) { + if (arg.startsWith(QLatin1String("/dev/"))) { + devices.append(arg); + args.removeAll(arg); + } + } + + // build new specification without /dev/ elements + m_spec = args.join(QLatin1Char(':')); + + foreach (const QString &device, devices) + addDevice(device); + + // when no devices specified, use device discovery to scan and monitor + if (devices.isEmpty()) { + qCDebug(qLcEvdevTablet) << "evdevtablet: Using device discovery"; + m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this); + if (m_deviceDiscovery) { + QStringList devices = m_deviceDiscovery->scanConnectedDevices(); + foreach (const QString &device, devices) + addDevice(device); + connect(m_deviceDiscovery, SIGNAL(deviceDetected(QString)), this, SLOT(addDevice(QString))); + connect(m_deviceDiscovery, SIGNAL(deviceRemoved(QString)), this, SLOT(removeDevice(QString))); + } + } +} + +QEvdevTabletManager::~QEvdevTabletManager() +{ + qDeleteAll(m_activeDevices); +} + +void QEvdevTabletManager::addDevice(const QString &deviceNode) +{ + qCDebug(qLcEvdevTablet) << "Adding device at" << deviceNode; + QEvdevTabletHandlerThread *handler; + handler = new QEvdevTabletHandlerThread(deviceNode, m_spec); + if (handler) { + m_activeDevices.insert(deviceNode, handler); + QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( + QInputDeviceManager::DeviceTypeTablet, m_activeDevices.count()); + } else { + qWarning("evdevtablet: Failed to open tablet device %s", qPrintable(deviceNode)); + } +} + +void QEvdevTabletManager::removeDevice(const QString &deviceNode) +{ + if (m_activeDevices.contains(deviceNode)) { + qCDebug(qLcEvdevTablet) << "Removing device at" << deviceNode; + QEvdevTabletHandlerThread *handler = m_activeDevices.value(deviceNode); + m_activeDevices.remove(deviceNode); + QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( + QInputDeviceManager::DeviceTypeTablet, m_activeDevices.count()); + delete handler; + } +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h b/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h new file mode 100644 index 0000000000..893ff03fa7 --- /dev/null +++ b/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVDEVTABLETMANAGER_P_H +#define QEVDEVTABLETMANAGER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QObject> +#include <QHash> +#include <QSocketNotifier> + +QT_BEGIN_NAMESPACE + +class QDeviceDiscovery; +class QEvdevTabletHandlerThread; + +class QEvdevTabletManager : public QObject +{ + Q_OBJECT +public: + QEvdevTabletManager(const QString &key, const QString &spec, QObject *parent = 0); + ~QEvdevTabletManager(); + +private slots: + void addDevice(const QString &deviceNode); + void removeDevice(const QString &deviceNode); + +private: + QString m_spec; + QDeviceDiscovery *m_deviceDiscovery; + QHash<QString, QEvdevTabletHandlerThread *> m_activeDevices; +}; + +QT_END_NAMESPACE + +#endif // QEVDEVTABLETMANAGER_P_H diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index ad348cc083..dc40f728e1 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -36,6 +36,7 @@ #include <QHash> #include <QSocketNotifier> #include <QGuiApplication> +#include <QTouchDevice> #include <QLoggingCategory> #include <QtCore/private/qcore_unix_p.h> #include <QtGui/private/qhighdpiscaling_p.h> diff --git a/src/platformsupport/input/libinput/qlibinputhandler.cpp b/src/platformsupport/input/libinput/qlibinputhandler.cpp index 5aa66a4eaf..58fbaacd2b 100644 --- a/src/platformsupport/input/libinput/qlibinputhandler.cpp +++ b/src/platformsupport/input/libinput/qlibinputhandler.cpp @@ -85,18 +85,18 @@ QLibInputHandler::QLibInputHandler(const QString &key, const QString &spec) Q_UNUSED(spec); m_udev = udev_new(); - if (!m_udev) + if (Q_UNLIKELY(!m_udev)) qFatal("Failed to get udev context for libinput"); m_li = libinput_udev_create_context(&liInterface, Q_NULLPTR, m_udev); - if (!m_li) + if (Q_UNLIKELY(!m_li)) qFatal("Failed to get libinput context"); libinput_log_set_handler(m_li, liLogHandler); if (qLcLibInput().isDebugEnabled()) libinput_log_set_priority(m_li, LIBINPUT_LOG_PRIORITY_DEBUG); - if (libinput_udev_assign_seat(m_li, "seat0")) + if (Q_UNLIKELY(libinput_udev_assign_seat(m_li, "seat0"))) qFatal("Failed to assign seat"); m_liFd = libinput_get_fd(m_li); diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 1ea6d0eb69..81c7faa389 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -25,5 +25,6 @@ contains(QT_CONFIG, dbus) { include(dbusmenu/dbusmenu.pri) include(dbustray/dbustray.pri) } +ios: include(graphics/graphics.pri) load(qt_module) diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp index 33cb4391f0..01efa1449f 100644 --- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp +++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp @@ -42,6 +42,8 @@ QT_BEGIN_NAMESPACE +#ifndef QT_NO_MULTIPROCESS + enum { debug = 0 }; static inline QByteArray detectDesktopEnvironment() @@ -149,4 +151,24 @@ bool QGenericUnixServices::openDocument(const QUrl &url) return launch(m_documentLauncher, url); } +#else +QByteArray QGenericUnixServices::desktopEnvironment() const +{ + return QByteArrayLiteral("UNKNOWN"); +} + +bool QGenericUnixServices::openUrl(const QUrl &url) +{ + qWarning("openUrl() not supported on this platform"); + return false; +} + +bool QGenericUnixServices::openDocument(const QUrl &url) +{ + qWarning("openDocument() not supported on this platform"); + return false; +} + +#endif // QT_NO_MULTIPROCESS + QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index 8f6171f217..ee62710913 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -616,7 +616,7 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const return QVariant(QGenericUnixTheme::xdgIconThemePaths()); case QPlatformTheme::StyleNames: { QStringList styleNames; - styleNames << QStringLiteral("GTK+") << QStringLiteral("fusion") << QStringLiteral("windows"); + styleNames << QStringLiteral("fusion") << QStringLiteral("windows"); return QVariant(styleNames); } case QPlatformTheme::KeyboardScheme: @@ -714,9 +714,9 @@ QStringList QGenericUnixTheme::themeNames() result.push_back(QLatin1String(QKdeTheme::name)); #endif } else if (gtkBasedEnvironments.contains(desktopName)) { - // prefer the GTK2 theme implementation with native dialogs etc. - result.push_back(QStringLiteral("gtk2")); - // fallback to the generic Gnome theme if loading the GTK2 theme fails + // prefer the GTK3 theme implementation with native dialogs etc. + result.push_back(QStringLiteral("gtk3")); + // fallback to the generic Gnome theme if loading the GTK3 theme fails result.push_back(QLatin1String(QGnomeTheme::name)); } } |