From 86b061b234b2dbe0225c602a36ba1595e2a6388c Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 29 Oct 2015 11:55:16 +0100 Subject: Mirclient: Avoid hardcoding the platform api choice When built in by the debian scripts, a symbol PLATFORM_API_TOUCH would be defined for relevant target platforms. Here in Qt, this does not apply. On a correctly installed system, the UBUNTU_PLATFORM_API_BACKEND variable is not required at runtime, since the system's value will be read from a settings file under /etc. Also, the previous hardcoding would mean that it could not be overridden at runtime. Change-Id: I24ddfaa254005b4113f3328b66edb1c6bbc509e2 Reviewed-by: Christian Stromme --- src/plugins/platforms/mirclient/qmirclientplugin.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.cpp b/src/plugins/platforms/mirclient/qmirclientplugin.cpp index 43d913f8d2..203a1cbfd8 100644 --- a/src/plugins/platforms/mirclient/qmirclientplugin.cpp +++ b/src/plugins/platforms/mirclient/qmirclientplugin.cpp @@ -49,11 +49,6 @@ QPlatformIntegration* QMirClientIntegrationPlugin::create(const QString &system, const QStringList &) { if (system.toLower() == "mirclient") { -#ifdef PLATFORM_API_TOUCH - setenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient", 1); -#else - setenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient", 1); -#endif return new QMirClientClientIntegration; } else { return 0; -- cgit v1.2.3 From 9599ee5ab7236130e3c375b56b6c0f00094e3a36 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 19 Nov 2015 20:33:45 +0100 Subject: Fix no-opengl build for texture backed widgets The recent changes added a widgetTexturesFor() helper function. There has to be a dummy version of this for -no-opengl builds because QPlatformTextureList is not available in such builds at all, meaning the real function is not suitable outside !QT_NO_OPENGL. Change-Id: Ib108b1804f539796631b1927de89937236781d2a Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qwidgetbackingstore.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 55b8513072..9036c28b9a 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1000,6 +1000,16 @@ void QPlatformTextureListWatcher::onLockStatusChanged(bool locked) if (!isLocked()) m_backingStore->sync(); } + +#else + +static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget) +{ + Q_UNUSED(tlw); + Q_UNUSED(widget); + return Q_NULLPTR; +} + #endif // QT_NO_OPENGL static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra) -- cgit v1.2.3 From 39c0d16a8e11ba7523a7dbeb3b1d6ee3ddfc09e8 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 19 Nov 2015 10:31:34 +0100 Subject: Send a paint after resize correctly from QOpenGLWidget Due to recreating the underlying framebuffer we absolutely need a re-render. However, going directly through paintGL() is wrong since application code may override paintEvent() instead. Such code would then miss these repaint requests. To overcome this, simply rely on paint events, like the normal code path does. Task-number: QTBUG-49466 Change-Id: I6ddb9eb53bedb1655a9714b9b77faa1c439766a2 Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qopenglwidget.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 3a4a3a0d63..a80db3f60b 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -1172,8 +1172,7 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *e) d->recreateFbo(); resizeGL(width(), height()); - d->invokeUserPaint(); - d->resolveSamples(); + d->sendPaintEvent(QRect(QPoint(0, 0), size())); } /*! -- cgit v1.2.3 From 436ad32f9f47787d0262c25e669b808c195c6565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Fri, 20 Nov 2015 15:44:30 +0100 Subject: xcb: Fix windows opened from keyboard are not active on Marco or Xfwm4 Windows opened from keyboard (e.g. keyboard shortcut) are not active on Marco or Xfwm4. These windows are under the window which received the key event. This patch fixes the problem by updating XCB timestamp on every key press like Qt4 does. Task-number: QTBUG-49567 Change-Id: I9ea483784ac361d0b645d0f11f643868b367ac2c Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 901764bbf8..50d49ca798 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1086,8 +1086,12 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) case XCB_FOCUS_OUT: HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent); case XCB_KEY_PRESS: - m_keyboard->updateXKBStateFromCore(((xcb_key_press_event_t *)event)->state); + { + xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event; + m_keyboard->updateXKBStateFromCore(kp->state); + setTime(kp->time); HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent); + } case XCB_KEY_RELEASE: m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state); HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent); -- cgit v1.2.3 From f39db6c3f8bc8dd3e38da40b5baf87da383bcc4a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 18 Nov 2015 13:36:02 +0100 Subject: Windows: Create one QPlatformCursor per screen. The pixmap-based cursors and some of the standard cursors we create from resource pixmaps need to be separated per screen. Use a QScopedPointer containing the per-screen cursor instead of the previously used QSharedPointer containing the cursor shared by all screens. Task-number: QTBUG-49511 Change-Id: I5203fcc4ecf5a7ff3fea833a4eaeb5300a6e6d54 Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowscursor.cpp | 9 ++++++--- src/plugins/platforms/windows/qwindowscursor.h | 3 ++- src/plugins/platforms/windows/qwindowsscreen.cpp | 12 +----------- src/plugins/platforms/windows/qwindowsscreen.h | 4 ++-- 4 files changed, 11 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 800b79347c..da121944c1 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -47,11 +47,12 @@ #include #include -static void initResources() +static bool initResources() { #if !defined (Q_OS_WINCE) && !defined (QT_NO_IMAGEFORMAT_PNG) Q_INIT_RESOURCE(cursors); #endif + return true; } QT_BEGIN_NAMESPACE @@ -590,9 +591,11 @@ CursorHandlePtr QWindowsCursor::pixmapWindowCursor(const QCursor &c) return it.value(); } -QWindowsCursor::QWindowsCursor() +QWindowsCursor::QWindowsCursor(const QPlatformScreen *screen) + : m_screen(screen) { - initResources(); + static const bool dummy = initResources(); + Q_UNUSED(dummy) } /*! diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index ac9e87d1fb..f1de5379d8 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -96,7 +96,7 @@ public: QPoint hotSpot; }; - QWindowsCursor(); + explicit QWindowsCursor(const QPlatformScreen *screen); void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE; QPoint pos() const Q_DECL_OVERRIDE; @@ -117,6 +117,7 @@ private: typedef QHash StandardCursorCache; typedef QHash PixmapCursorCache; + const QPlatformScreen *const m_screen; StandardCursorCache m_standardCursorCache; PixmapCursorCache m_pixmapCursorCache; }; diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index de4ef79b81..e69665e4a9 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -195,16 +195,6 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) } #endif // !QT_NO_DEBUG_STREAM -// Return the cursor to be shared by all screens (virtual desktop). -static inline QSharedPointer sharedCursor() -{ -#ifndef QT_NO_CURSOR - if (const QScreen *primaryScreen = QGuiApplication::primaryScreen()) - return static_cast(primaryScreen->handle())->cursorPtr(); -#endif - return QSharedPointer(new QWindowsCursor); -} - /*! \class QWindowsScreen \brief Windows screen. @@ -216,7 +206,7 @@ static inline QSharedPointer sharedCursor() QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) : m_data(data) #ifndef QT_NO_CURSOR - ,m_cursor(sharedCursor()) + , m_cursor(new QWindowsCursor(this)) #endif { } diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index bc8fbf553b..879cda047e 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include QT_BEGIN_NAMESPACE @@ -74,7 +74,7 @@ class QWindowsScreen : public QPlatformScreen { public: #ifndef QT_NO_CURSOR - typedef QSharedPointer CursorPtr; + typedef QScopedPointer CursorPtr; #endif explicit QWindowsScreen(const QWindowsScreenData &data); -- cgit v1.2.3 From 36bb6d266e08ff4ae3c45d2ad428f7f787746b8a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 19 Nov 2015 13:32:25 +0100 Subject: Windows: Scale pixmap/bitmap cursors when High DPI scaling is active. Apply a per screen scale factor, also taking the device pixel ratios of the pixmaps into account. Task-number: QTBUG-49511 Change-Id: If46b6eeb37635c2c4046992c1ba06711ccf54eae Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscursor.cpp | 26 +++++++++++++++++++----- src/plugins/platforms/windows/qwindowscursor.h | 4 ++-- 2 files changed, 23 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index da121944c1..7dfaf201cd 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -43,6 +43,7 @@ #include #include #include // getPixmapCursor() +#include #include #include @@ -93,9 +94,14 @@ QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c) \sa QWindowsWindowCursor */ -HCURSOR QWindowsCursor::createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot) +HCURSOR QWindowsCursor::createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor) { HCURSOR cur = 0; + scaleFactor /= pixmap.devicePixelRatioF(); + if (!qFuzzyCompare(scaleFactor, 1)) { + pixmap = pixmap.scaled((scaleFactor * QSizeF(pixmap.size())).toSize(), + Qt::KeepAspectRatio, Qt::SmoothTransformation); + } QBitmap mask = pixmap.mask(); if (mask.isNull()) { mask = QBitmap(pixmap.size()); @@ -203,11 +209,19 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits, } // Create a cursor from image and mask of the format QImage::Format_Mono. -static HCURSOR createBitmapCursor(const QCursor &cursor) +static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1) { Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap()); - const QImage bbits = cursor.bitmap()->toImage().convertToFormat(QImage::Format_Mono); - const QImage mbits = cursor.mask()->toImage().convertToFormat(QImage::Format_Mono); + QImage bbits = cursor.bitmap()->toImage(); + QImage mbits = cursor.mask()->toImage(); + scaleFactor /= bbits.devicePixelRatioF(); + if (!qFuzzyCompare(scaleFactor, 1)) { + const QSize scaledSize = (QSizeF(bbits.size()) * scaleFactor).toSize(); + bbits = bbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + mbits = mbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + bbits = bbits.convertToFormat(QImage::Format_Mono); + mbits = mbits.convertToFormat(QImage::Format_Mono); const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1)); const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1)); return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm); @@ -583,9 +597,11 @@ CursorHandlePtr QWindowsCursor::pixmapWindowCursor(const QCursor &c) ++it; } } + const qreal scaleFactor = QHighDpiScaling::factor(m_screen); const QPixmap pixmap = c.pixmap(); const HCURSOR hc = pixmap.isNull() - ? createBitmapCursor(c) : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot()); + ? createBitmapCursor(c, scaleFactor) + : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot(), scaleFactor); it = m_pixmapCursorCache.insert(cacheKey, CursorHandlePtr(new CursorHandle(hc))); } return it.value(); diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index f1de5379d8..ac4462f131 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -102,8 +102,8 @@ public: QPoint pos() const Q_DECL_OVERRIDE; void setPos(const QPoint &pos) Q_DECL_OVERRIDE; - static HCURSOR createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot); - static HCURSOR createPixmapCursor(const PixmapCursor &pc) { return createPixmapCursor(pc.pixmap, pc.hotSpot); } + static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1); + static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); } static PixmapCursor customCursor(Qt::CursorShape cursorShape); static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape); -- cgit v1.2.3 From 05c8e51d884d7130e3f26701a7955ebc2026bb12 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 19 Nov 2015 13:39:52 +0100 Subject: Windows: Scale cursors from resource pixmaps according to screen. QWindowsCursor::customCursor() uses a best match algorithm to find the most suitable pixmap for the cursor size obtained from GetSystemMetrics(). This size is correct for the primary screen only; in High DPI + normal monitor multiscreen-environments, the cursors will be too large on the secondary monitor. Pass the platform screen to apply a correction factor based on logical DPI to obtain the correct size. Task-number: QTBUG-49511 Change-Id: I8a64a969e3ade7ab5029e3ae904a0bcbb4704f90 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscursor.cpp | 45 +++++++++++++++++------- src/plugins/platforms/windows/qwindowscursor.h | 4 +-- 2 files changed, 34 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 7dfaf201cd..c138335b4b 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -227,7 +227,25 @@ static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1) return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm); } -static inline QSize systemCursorSize() { return QSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); } +static QSize systemCursorSize(const QPlatformScreen *screen = Q_NULLPTR) +{ + const QSize primaryScreenCursorSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); + if (screen) { + // Correct the size if the DPI value of the screen differs from + // that of the primary screen. + if (const QScreen *primaryQScreen = QGuiApplication::primaryScreen()) { + const QPlatformScreen *primaryScreen = primaryQScreen->handle(); + if (screen != primaryScreen) { + const qreal logicalDpi = screen->logicalDpi().first; + const qreal primaryScreenLogicalDpi = primaryScreen->logicalDpi().first; + if (!qFuzzyCompare(logicalDpi, primaryScreenLogicalDpi)) + return (QSizeF(primaryScreenCursorSize) * logicalDpi / primaryScreenLogicalDpi).toSize(); + } + } + } + return primaryScreenCursorSize; +} + static inline QSize standardCursorSize() { return QSize(32, 32); } #if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG) @@ -257,7 +275,8 @@ static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &syst return QWindowsCursor::PixmapCursor(rawImage, hotSpot); } -QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape) +QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape, + const QPlatformScreen *screen) { // Non-standard Windows cursors are created from bitmaps static const uchar vsplit_bits[] = { @@ -425,13 +444,13 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor switch (cursorShape) { case Qt::SplitVCursor: - return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, vsplit_bits, vsplitm_bits); + return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, vsplit_bits, vsplitm_bits); case Qt::SplitHCursor: - return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, hsplit_bits, hsplitm_bits); + return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, hsplit_bits, hsplitm_bits); case Qt::OpenHandCursor: - return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, openhand_bits, openhandm_bits); + return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, openhand_bits, openhandm_bits); case Qt::ClosedHandCursor: - return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, closedhand_bits, closedhandm_bits); + return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, closedhand_bits, closedhandm_bits); case Qt::DragCopyCursor: return QWindowsCursor::PixmapCursor(QPixmap(copyDragCursorXpmC), QPoint(0, 0)); case Qt::DragMoveCursor: @@ -451,7 +470,7 @@ struct QWindowsCustomPngCursor { int hotSpotY; }; -QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape) +QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen) { static const QWindowsCustomPngCursor pngCursors[] = { { Qt::SplitVCursor, 32, "splitvcursor_32.png", 11, 11 }, @@ -477,14 +496,14 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor { Qt::DragLinkCursor, 64, "draglinkcursor_64.png", 0, 0 } }; - const int cursorSize = GetSystemMetrics(SM_CXCURSOR); + const QSize cursorSize = systemCursorSize(screen); const QWindowsCustomPngCursor *sEnd = pngCursors + sizeof(pngCursors) / sizeof(pngCursors[0]); const QWindowsCustomPngCursor *bestFit = 0; int sizeDelta = INT_MAX; for (const QWindowsCustomPngCursor *s = pngCursors; s < sEnd; ++s) { if (s->shape != cursorShape) continue; - const int currentSizeDelta = qMax(s->size, cursorSize) - qMin(s->size, cursorSize); + const int currentSizeDelta = qMax(s->size, cursorSize.width()) - qMin(s->size, cursorSize.width()); if (currentSizeDelta < sizeDelta) { bestFit = s; if (currentSizeDelta == 0) @@ -507,7 +526,7 @@ struct QWindowsStandardCursorMapping { LPCWSTR resource; }; -HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape) +HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen) { Q_ASSERT(cursorShape != Qt::BitmapCursor); @@ -530,7 +549,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape) switch (cursorShape) { case Qt::BlankCursor: { - QImage blank = QImage(systemCursorSize(), QImage::Format_Mono); + QImage blank = QImage(systemCursorSize(screen), QImage::Format_Mono); blank.fill(0); // ignore color table return createBitmapCursor(blank, blank); } @@ -541,7 +560,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape) case Qt::DragCopyCursor: case Qt::DragMoveCursor: case Qt::DragLinkCursor: - return QWindowsCursor::createPixmapCursor(customCursor(cursorShape)); + return QWindowsCursor::createPixmapCursor(customCursor(cursorShape, screen)); default: break; } @@ -570,7 +589,7 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) { StandardCursorCache::Iterator it = m_standardCursorCache.find(shape); if (it == m_standardCursorCache.end()) { - if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape)) + if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape, m_screen)) it = m_standardCursorCache.insert(shape, CursorHandlePtr(new CursorHandle(hc))); } return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle); diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index ac4462f131..558e807201 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -104,9 +104,9 @@ public: static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1); static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); } - static PixmapCursor customCursor(Qt::CursorShape cursorShape); + static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR); - static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape); + static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR); static QPoint mousePosition(); static CursorState cursorState(); -- cgit v1.2.3 From 07efdb78f03fb2f75898cc769b3224baee4d8d90 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 19 Nov 2015 14:14:37 +0100 Subject: Windows: Fix the size of drag cursors in multi-screen setups. Move QWindowsDrag::defaultCursor() to the per-screen instance of QWindowsCursor so that the cached default drag cursor pixmaps are created with the correct size per screen. Task-number: QTBUG-49511 Change-Id: I02f75ac3b1e5e064325b066ee03e1d5c8a7c7ee8 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowscursor.cpp | 88 ++++++++++++++++++ src/plugins/platforms/windows/qwindowscursor.h | 7 ++ src/plugins/platforms/windows/qwindowsdrag.cpp | 111 +++-------------------- src/plugins/platforms/windows/qwindowsdrag.h | 10 +- 4 files changed, 111 insertions(+), 105 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index c138335b4b..c769eb04a4 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -692,6 +692,94 @@ void QWindowsCursor::setPos(const QPoint &pos) SetCursorPos(pos.x() , pos.y()); } +QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const +{ + switch (action) { + case Qt::CopyAction: + if (m_copyDragCursor.isNull()) + m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor, m_screen).pixmap; + return m_copyDragCursor; + case Qt::TargetMoveAction: + case Qt::MoveAction: + if (m_moveDragCursor.isNull()) + m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor, m_screen).pixmap; + return m_moveDragCursor; + case Qt::LinkAction: + if (m_linkDragCursor.isNull()) + m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor, m_screen).pixmap; + return m_linkDragCursor; + default: + break; + } + + static const char * const ignoreDragCursorXpmC[] = { + "24 30 3 1", + ". c None", + "a c #000000", + "X c #FFFFFF", + "aa......................", + "aXa.....................", + "aXXa....................", + "aXXXa...................", + "aXXXXa..................", + "aXXXXXa.................", + "aXXXXXXa................", + "aXXXXXXXa...............", + "aXXXXXXXXa..............", + "aXXXXXXXXXa.............", + "aXXXXXXaaaa.............", + "aXXXaXXa................", + "aXXaaXXa................", + "aXa..aXXa...............", + "aa...aXXa...............", + "a.....aXXa..............", + "......aXXa.....XXXX.....", + ".......aXXa..XXaaaaXX...", + ".......aXXa.XaaaaaaaaX..", + "........aa.XaaaXXXXaaaX.", + "...........XaaaaX..XaaX.", + "..........XaaXaaaX..XaaX", + "..........XaaXXaaaX.XaaX", + "..........XaaX.XaaaXXaaX", + "..........XaaX..XaaaXaaX", + "...........XaaX..XaaaaX.", + "...........XaaaXXXXaaaX.", + "............XaaaaaaaaX..", + ".............XXaaaaXX...", + "...............XXXX....."}; + + if (m_ignoreDragCursor.isNull()) { +#if !defined (Q_OS_WINCE) + HCURSOR cursor = LoadCursor(NULL, IDC_NO); + ICONINFO iconInfo = {0, 0, 0, 0, 0}; + GetIconInfo(cursor, &iconInfo); + BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0}; + + if (iconInfo.hbmColor + && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor) + && bmColor.bmWidth == bmColor.bmWidthBytes / 4) { + const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes; + uchar *colorBits = new uchar[colorBitsLength]; + GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits); + const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight, + bmColor.bmWidthBytes, QImage::Format_ARGB32); + + m_ignoreDragCursor = QPixmap::fromImage(colorImage); + delete [] colorBits; + } else { + m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC); + } + + DeleteObject(iconInfo.hbmMask); + DeleteObject(iconInfo.hbmColor); + DestroyCursor(cursor); +#else // !Q_OS_WINCE + m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC); +#endif // !Q_OS_WINCE + } + return m_ignoreDragCursor; +} + /*! \class QWindowsWindowCursor \brief Per-Window cursor. Contains a QCursor and manages its associated system diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 558e807201..e93f779f94 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -113,6 +113,8 @@ public: CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor); CursorHandlePtr pixmapWindowCursor(const QCursor &c); + QPixmap dragDefaultCursor(Qt::DropAction action) const; + private: typedef QHash StandardCursorCache; typedef QHash PixmapCursorCache; @@ -120,6 +122,11 @@ private: const QPlatformScreen *const m_screen; StandardCursorCache m_standardCursorCache; PixmapCursorCache m_pixmapCursorCache; + + mutable QPixmap m_copyDragCursor; + mutable QPixmap m_moveDragCursor; + mutable QPixmap m_linkDragCursor; + mutable QPixmap m_ignoreDragCursor; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index e16bb80714..021058fa33 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -271,13 +271,6 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e) } #endif // !QT_NO_DEBUG_STREAM -static qreal dragScaleFactor() -{ - const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager(); - const QWindowsScreen *screen = screenManager.screenAtDp(QWindowsCursor::mousePosition()); - return screen ? QHighDpiScaling::factor(screen) : qreal(1); -} - /*! \brief Blend custom pixmap with cursors. */ @@ -288,7 +281,17 @@ void QWindowsOleDropSource::createCursors() const QPixmap pixmap = drag->pixmap(); const bool hasPixmap = !pixmap.isNull(); - const qreal scaleFactor = dragScaleFactor(); + // Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget. + + qreal scaleFactor = 1; + QPlatformCursor *platformCursor = Q_NULLPTR; + if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) { + scaleFactor = QHighDpiScaling::factor(platformScreen); + platformCursor = platformScreen->cursor(); + } + if (!platformCursor && QGuiApplication::primaryScreen()) + platformCursor = QGuiApplication::primaryScreen()->handle()->cursor(); + const bool scalePixmap = hasPixmap && m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled. && (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio())); @@ -306,8 +309,8 @@ void QWindowsOleDropSource::createCursors() for (int cnum = 0; cnum < actionCount; ++cnum) { const Qt::DropAction action = actions[cnum]; QPixmap cursorPixmap = drag->dragCursor(action); - if (cursorPixmap.isNull()) - cursorPixmap = m_drag->defaultCursor(action); + if (cursorPixmap.isNull() && platformCursor) + cursorPixmap = static_cast(platformCursor)->dragDefaultCursor(action); const qint64 cacheKey = cursorPixmap.cacheKey(); const ActionCursorMapIt it = m_cursors.find(action); if (it != m_cursors.end() && it.value().cacheKey == cacheKey) @@ -704,94 +707,6 @@ IDropTargetHelper* QWindowsDrag::dropHelper() { return m_cachedDropTargetHelper; } -QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const -{ - switch (action) { - case Qt::CopyAction: - if (m_copyDragCursor.isNull()) - m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap; - return m_copyDragCursor; - case Qt::TargetMoveAction: - case Qt::MoveAction: - if (m_moveDragCursor.isNull()) - m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap; - return m_moveDragCursor; - case Qt::LinkAction: - if (m_linkDragCursor.isNull()) - m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap; - return m_linkDragCursor; - default: - break; - } - - static const char * const ignoreDragCursorXpmC[] = { - "24 30 3 1", - ". c None", - "a c #000000", - "X c #FFFFFF", - "aa......................", - "aXa.....................", - "aXXa....................", - "aXXXa...................", - "aXXXXa..................", - "aXXXXXa.................", - "aXXXXXXa................", - "aXXXXXXXa...............", - "aXXXXXXXXa..............", - "aXXXXXXXXXa.............", - "aXXXXXXaaaa.............", - "aXXXaXXa................", - "aXXaaXXa................", - "aXa..aXXa...............", - "aa...aXXa...............", - "a.....aXXa..............", - "......aXXa.....XXXX.....", - ".......aXXa..XXaaaaXX...", - ".......aXXa.XaaaaaaaaX..", - "........aa.XaaaXXXXaaaX.", - "...........XaaaaX..XaaX.", - "..........XaaXaaaX..XaaX", - "..........XaaXXaaaX.XaaX", - "..........XaaX.XaaaXXaaX", - "..........XaaX..XaaaXaaX", - "...........XaaX..XaaaaX.", - "...........XaaaXXXXaaaX.", - "............XaaaaaaaaX..", - ".............XXaaaaXX...", - "...............XXXX....."}; - - if (m_ignoreDragCursor.isNull()) { -#if !defined (Q_OS_WINCE) - HCURSOR cursor = LoadCursor(NULL, IDC_NO); - ICONINFO iconInfo = {0, 0, 0, 0, 0}; - GetIconInfo(cursor, &iconInfo); - BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0}; - - if (iconInfo.hbmColor - && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor) - && bmColor.bmWidth == bmColor.bmWidthBytes / 4) { - const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes; - uchar *colorBits = new uchar[colorBitsLength]; - GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits); - const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight, - bmColor.bmWidthBytes, QImage::Format_ARGB32); - - m_ignoreDragCursor = QPixmap::fromImage(colorImage); - delete [] colorBits; - } else { - m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC); - } - - DeleteObject(iconInfo.hbmMask); - DeleteObject(iconInfo.hbmColor); - DestroyCursor(cursor); -#else // !Q_OS_WINCE - m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC); -#endif // !Q_OS_WINCE - } - return m_ignoreDragCursor; -} - Qt::DropAction QWindowsDrag::drag(QDrag *drag) { // TODO: Accessibility handling? diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h index 9a5e0b17f2..890ad6c142 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.h +++ b/src/plugins/platforms/windows/qwindowsdrag.h @@ -42,6 +42,9 @@ struct IDropTargetHelper; QT_BEGIN_NAMESPACE + +class QPlatformScreen; + class QWindowsDropMimeData : public QWindowsInternalMimeData { public: QWindowsDropMimeData() {} @@ -95,18 +98,11 @@ public: IDropTargetHelper* dropHelper(); - QPixmap defaultCursor(Qt::DropAction action) const; - private: QWindowsDropMimeData m_dropData; IDataObject *m_dropDataObject; IDropTargetHelper* m_cachedDropTargetHelper; - - mutable QPixmap m_copyDragCursor; - mutable QPixmap m_moveDragCursor; - mutable QPixmap m_linkDragCursor; - mutable QPixmap m_ignoreDragCursor; }; QT_END_NAMESPACE -- cgit v1.2.3 From 084df84bd096fe78eec5edd62424bd625dcfc00b Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Wed, 18 Nov 2015 17:11:07 +0700 Subject: QPI/Cocoa: QNSView - guard removeFromSuperview by autorelease pool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit removeFromSuperview could be called from outside the Qt domain (e.g from a native cocoa gui). we need to guard it by an autorelease pool to make sure that potential release/dealloc methods are not postponed to a point when we do not have a qapplication anymore Change-Id: If65cce4c524a16ffee125694c534f900c7d08fa8 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview.h | 1 + src/plugins/platforms/cocoa/qnsview.mm | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index bad67f2516..50b456cab7 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -99,6 +99,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification; - (void)viewDidHide; - (void)viewDidUnhide; +- (void)removeFromSuperview; - (BOOL)isFlipped; - (BOOL)acceptsFirstResponder; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index f414193bdb..3faa292ae0 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -498,6 +498,12 @@ QT_WARNING_POP m_platformWindow->exposeWindow(); } +- (void)removeFromSuperview +{ + QMacAutoReleasePool pool; + [super removeFromSuperview]; +} + - (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset { m_backingStore = backingStore; -- cgit v1.2.3 From 1ab7880d73fa94befbeb5cdca3fd6d3bbd25f5ba Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 5 Nov 2015 05:49:07 +0400 Subject: Get rid of QT_USE_BUNDLED_LIBPNG In fact, this is an extra info no one ever cares about. We already have properly configured INCLUDEPATH to look for png.h. Change-Id: I27fec4d474570683c6c371dff34472a7c650fe65 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/3rdparty/libpng.pri | 1 - src/gui/image/qpnghandler.cpp | 5 ----- 2 files changed, 6 deletions(-) (limited to 'src') diff --git a/src/3rdparty/libpng.pri b/src/3rdparty/libpng.pri index f8516bd5db..a5fe32f867 100644 --- a/src/3rdparty/libpng.pri +++ b/src/3rdparty/libpng.pri @@ -1,4 +1,3 @@ -DEFINES *= QT_USE_BUNDLED_LIBPNG DEFINES += PNG_ARM_NEON_OPT=0 INCLUDEPATH += $$PWD/libpng SOURCES += $$PWD/libpng/png.c \ diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 776a61d8fe..e9944e1750 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -43,13 +43,8 @@ #include #include -#ifdef QT_USE_BUNDLED_LIBPNG -#include <../../3rdparty/libpng/png.h> -#include <../../3rdparty/libpng/pngconf.h> -#else #include #include -#endif #if PNG_LIBPNG_VER >= 10400 && PNG_LIBPNG_VER <= 10502 \ && defined(PNG_PEDANTIC_WARNINGS_SUPPORTED) -- cgit v1.2.3 From 0e99f3c853aa10f60aa33804c122b187edb565ea Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 23 Nov 2015 14:04:57 +0400 Subject: QTextLine::cursorToX: Always return the nearest valid cursor position The documentation already states we're doing this, so stop lying and implement it properly :) Change-Id: Ic78980d76f61e8aa64e59ea058a8105d9c507774 Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 9f046af47c..e69a591d59 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2624,26 +2624,26 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR */ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const { - if (!eng->layoutData) - eng->itemize(); - const QScriptLine &line = eng->lines[index]; bool lastLine = index >= eng->lines.size() - 1; QFixed x = line.x; - x += eng->alignLine(line) - eng->leadingSpaceWidth(line); - if (!index && !eng->layoutData->items.size()) { - *cursorPos = 0; + if (!eng->layoutData) + eng->itemize(); + if (!eng->layoutData->items.size()) { + *cursorPos = line.from; return x.toReal(); } + x += eng->alignLine(line) - eng->leadingSpaceWidth(line); + int lineEnd = line.from + line.length + line.trailingSpaces; - int pos = qBound(0, *cursorPos, lineEnd); + int pos = qBound(line.from, *cursorPos, lineEnd); int itm; const QCharAttributes *attributes = eng->attributes(); if (!attributes) { - *cursorPos = 0; + *cursorPos = line.from; return x.toReal(); } while (pos < lineEnd && !attributes[pos].graphemeBoundary) @@ -2655,7 +2655,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const else itm = eng->findItem(pos); if (itm < 0) { - *cursorPos = 0; + *cursorPos = line.from; return x.toReal(); } eng->shapeLine(line); -- cgit v1.2.3 From 073a16e50e5803fc92dc46bca704f8a7ef79e597 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 21 Nov 2015 00:34:43 +0400 Subject: QTextLine::cursorToX: Optimize by re-using the cached values (and move some code around) Change-Id: I2e26dcc7b769fdbcc750332845da11ec88e332dd Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index e69a591d59..67af3d316b 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2663,18 +2663,14 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const const QScriptItem *si = &eng->layoutData->items[itm]; if (!si->num_glyphs) eng->shape(itm); - pos -= si->position; + + const int l = eng->length(itm); + pos = qBound(0, pos - si->position, l); QGlyphLayout glyphs = eng->shapedGlyphs(si); unsigned short *logClusters = eng->logClusters(si); Q_ASSERT(logClusters); - int l = eng->length(itm); - if (pos > l) - pos = l; - if (pos < 0) - pos = 0; - int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos]; if (edge == Trailing && glyph_pos < si->num_glyphs) { // trailing edge is leading edge of next cluster @@ -2683,7 +2679,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const glyph_pos++; } - bool reverse = eng->layoutData->items[itm].analysis.bidiLevel % 2; + bool reverse = si->analysis.bidiLevel % 2; // add the items left of the cursor @@ -2710,13 +2706,15 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const x += si.width; continue; } + + const int itemLength = eng->length(item); int start = qMax(line.from, si.position); - int end = qMin(lineEnd, si.position + eng->length(item)); + int end = qMin(lineEnd, si.position + itemLength); logClusters = eng->logClusters(&si); int gs = logClusters[start-si.position]; - int ge = (end == si.position + eng->length(item)) ? si.num_glyphs-1 : logClusters[end-si.position-1]; + int ge = (end == si.position + itemLength) ? si.num_glyphs-1 : logClusters[end-si.position-1]; QGlyphLayout glyphs = eng->shapedGlyphs(&si); -- cgit v1.2.3 From fa00afe7d760d91cf9c91f57dd2f77625e758e28 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 21 Nov 2015 01:04:39 +0400 Subject: Optimize QTextEngine::findItem() usage cases Since the item positions are guaranteed to grow, we could safely re-use the obtained first item while looking for the last item in the chain. Change-Id: I5e42f5de820c62a51a109a4b227b031c697aa898 Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 13 +++++++------ src/gui/text/qtextengine_p.h | 2 +- src/gui/text/qtextlayout.cpp | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 50a242d81e..31b1109b6a 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -918,10 +918,11 @@ void QTextEngine::shapeLine(const QScriptLine &line) { QFixed x; bool first = true; - const int end = findItem(line.from + line.length - 1); int item = findItem(line.from); if (item == -1) return; + + const int end = findItem(line.from + line.length - 1, item); for ( ; item <= end; ++item) { QScriptItem &si = layoutData->items[item]; if (si.analysis.flags == QScriptAnalysis::Tab) { @@ -1747,13 +1748,13 @@ bool QTextEngine::isRightToLeft() const } -int QTextEngine::findItem(int strPos) const +int QTextEngine::findItem(int strPos, int firstItem) const { itemize(); - if (strPos < 0 || strPos >= layoutData->string.size()) + if (strPos < 0 || strPos >= layoutData->string.size() || firstItem < 0) return -1; - int left = 1; + int left = firstItem + 1; int right = layoutData->items.size()-1; while(left <= right) { int middle = ((right-left)/2)+left; @@ -2172,7 +2173,7 @@ void QTextEngine::justify(const QScriptLine &line) return; int firstItem = findItem(line.from); - int lastItem = findItem(line.from + line_length - 1); + int lastItem = findItem(line.from + line_length - 1, firstItem); int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0; QVarLengthArray justificationPoints; @@ -3529,7 +3530,7 @@ QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, co lineNum(_lineNum), lineEnd(line.from + line.length), firstItem(eng->findItem(line.from)), - lastItem(eng->findItem(lineEnd - 1)), + lastItem(eng->findItem(lineEnd - 1, firstItem)), nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0), logicalItem(-1), item(-1), diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index dbe8e1ee2b..39c228fd52 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -512,7 +512,7 @@ public: void freeMemory(); - int findItem(int strPos) const; + int findItem(int strPos, int firstItem = 0) const; inline QTextFormatCollection *formatCollection() const { if (block.docHandle()) return block.docHandle()->formatCollection(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 67af3d316b..5f570fea82 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2685,7 +2685,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const // add the items left of the cursor int firstItem = eng->findItem(line.from); - int lastItem = eng->findItem(lineEnd - 1); + int lastItem = eng->findItem(lineEnd - 1, itm); int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0; QVarLengthArray visualOrder(nItems); @@ -2786,7 +2786,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const return line.from; int firstItem = eng->findItem(line.from); - int lastItem = eng->findItem(line.from + line_length - 1); + int lastItem = eng->findItem(line.from + line_length - 1, firstItem); int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0; if (!nItems) -- cgit v1.2.3 From 5b62a5e7aabcc818408f2fe28b9760082f474def Mon Sep 17 00:00:00 2001 From: Samuel Nevala Date: Thu, 19 Nov 2015 13:12:41 +0200 Subject: Fix deadlock when setting environment variables. Qt uses QHash as the container for faking environment variables on Windows Runtime and CE. Environment variable manipulation functions are protected by mutex. Accessing the QT_HASH_SEED environment variable inside QHash can lead to situation where qputenv() call leads to qgetenv() call and that leads to a deadlock. Since the application environment is faked anyway, drop support for QT_HASH_SEED and ifdef that functionality out on those platforms. Documentation is updated to reflect changes. Task-number: QTBUG-49529 Change-Id: I1b1c28cb0b041fe2a63ca3dce57068fcb46505a7 Reviewed-by: Oswald Buddenhagen Reviewed-by: Andrew Knight --- src/corelib/tools/qhash.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index b334a697a9..fe49e8c6a8 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -38,6 +38,14 @@ #ifndef _CRT_RAND_S #define _CRT_RAND_S #endif + +// Windows Runtime and CE use a QHash to fake environment variables. To avoid +// deadlock, disable reading the QT_HASH_SEED environment variable within +// QHash. +#if defined(Q_OS_WINRT) || defined(Q_OS_WINCE) +# define QHASH_NO_ENV_SEED +#endif + #include #include "qhash.h" @@ -223,9 +231,11 @@ static uint qt_create_qhash_seed() uint seed = 0; #ifndef QT_BOOTSTRAPPED +#ifdef QHASH_NO_ENV_SEED QByteArray envSeed = qgetenv("QT_HASH_SEED"); if (!envSeed.isNull()) return envSeed.toUInt(); +#endif // QHASH_NO_ENV_SEED #ifdef Q_OS_UNIX int randomfd = qt_safe_open("/dev/urandom", O_RDONLY); @@ -327,8 +337,10 @@ int qGlobalQHashSeed() */ void qSetGlobalQHashSeed(int newSeed) { +#ifdef QHASH_NO_ENV_SEED if (qEnvironmentVariableIsSet("QT_HASH_SEED")) return; +#endif // QHASH_NO_ENV_SEED if (newSeed == -1) { int x(qt_create_qhash_seed() & INT_MAX); qt_qhash_seed.store(x); @@ -1182,6 +1194,9 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW decimal value, will be used as the seed for qHash(). Alternatively, you can call the qSetGlobalQHashSeed() function. + \note The environment variable \c QT_HASH_SEED is unsupported on Windows + Runtime and CE. Use qSetGlobalQHashSeed() instead on those platforms. + \sa QHashIterator, QMutableHashIterator, QMap, QSet */ -- cgit v1.2.3 From 837b5d458970f3981859cb9dfa0cec5fcd6d0c4f Mon Sep 17 00:00:00 2001 From: Tilo Nitzsche Date: Mon, 23 Nov 2015 19:28:25 +0100 Subject: Fix undefined behavior in qRgba(). Shifting a signed integer that overflows is undefined behavior. All masks were changed to unsigned in qRgb and qRgba. While the alpha value is enough to fix the undefined behavior, Visual C++ generates slow code if not all of those constants are unsigned. Change-Id: Ia0ec3e9464088495173b4ad9c2e37a49e6f8e987 Task-number: QTBUG-49595 Reviewed-by: Thiago Macieira --- src/gui/painting/qrgb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gui/painting/qrgb.h b/src/gui/painting/qrgb.h index f7f2185bef..ca9fc03d14 100644 --- a/src/gui/painting/qrgb.h +++ b/src/gui/painting/qrgb.h @@ -58,10 +58,10 @@ inline Q_DECL_CONSTEXPR int qAlpha(QRgb rgb) // get alpha part of { return rgb >> 24; } inline Q_DECL_CONSTEXPR QRgb qRgb(int r, int g, int b)// set RGB value -{ return (0xffu << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); } +{ return (0xffu << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); } inline Q_DECL_CONSTEXPR QRgb qRgba(int r, int g, int b, int a)// set RGBA value -{ return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); } +{ return ((a & 0xffu) << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); } inline Q_DECL_CONSTEXPR int qGray(int r, int g, int b)// convert R,G,B to gray 0..255 { return (r*11+g*16+b*5)/32; } -- cgit v1.2.3 From 4fd1e5f40c791a920007e842252229826d20c9c9 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 24 Nov 2015 12:39:23 +0100 Subject: winrt: Fix text rendering This is a partial revert of aecf3006bddb959795d03dd72d9c520e49713913. The DPI needs to be set inside the constructor to have the text rendering initialize properly. Landscape orientation fix is still valid and the dpi change was unrelated to resolve QTBUG-49470. Task-number: QTBUG-49610 Task-number: QTBUG-49470 Change-Id: I928b8d291b65cd744731c009917804b96253c276 Reviewed-by: Samuel Nevala Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 158917184c..a642443386 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -507,6 +507,8 @@ QWinRTScreen::QWinRTScreen() hr = d->displayInformation->get_NativeOrientation(&displayOrientation); Q_ASSERT_SUCCEEDED(hr); d->nativeOrientation = static_cast(static_cast(qtOrientationsFromNative(displayOrientation))); + // Set initial pixel density + onDpiChanged(Q_NULLPTR, Q_NULLPTR); d->orientation = d->nativeOrientation; ComPtr applicationViewStatics; @@ -753,7 +755,6 @@ void QWinRTScreen::initialize() Q_ASSERT_SUCCEEDED(hr); hr = d->displayInformation->add_DpiChanged(Callback(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]); Q_ASSERT_SUCCEEDED(hr); - onDpiChanged(Q_NULLPTR, Q_NULLPTR); onOrientationChanged(Q_NULLPTR, Q_NULLPTR); onVisibilityChanged(nullptr, nullptr); } -- cgit v1.2.3 From f30b75e569332558add552cde2b988c3a65e98cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 16 Nov 2015 14:25:48 +0100 Subject: xcb: Don't assume creating a window will result in ConfigureNotify event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We assumed that creating a window would always result in a configure notify event, so we delayed sending the initial expose event until receiving the configure notify. That strategy fails in cases where the window does not need a reconfigure after being created, such as when not running a window manager, or when creating child windows. In those cases the window is just mapped, and we ended up never sending an expose event. The problem was masked by sometimes receiving an explicit expose event from X, just after the mapped notification, which we then sent without waiting for configure. Unfortunately we can't rely on this behavior and need to remove the deferred expose event logic, so that we always ensure that at least one expose event is sent to Qt. Change-Id: I702be7f24de2a1e89c085fb6bd95bb8ff7792a27 Reviewed-by: Laszlo Agocs Reviewed-by: Uli Schlachter Reviewed-by: Frederik Gladhorn Reviewed-by: Jędrzej Nowacki --- src/plugins/platforms/xcb/qxcbwindow.cpp | 14 +++----------- src/plugins/platforms/xcb/qxcbwindow.h | 2 -- 2 files changed, 3 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index d76f1245e8..6023ee6b29 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -314,8 +314,6 @@ void QXcbWindow::create() destroy(); - m_deferredExpose = false; - m_configureNotifyPending = true; m_windowState = Qt::WindowNoState; Qt::WindowType type = window()->type(); @@ -2022,12 +2020,8 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * if (newScreen != currentScreen) QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); - m_configureNotifyPending = false; - - if (m_deferredExpose) { - m_deferredExpose = false; + if (m_mapped) QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - } if (m_usingSyncProtocol && m_syncState == SyncReceived) m_syncState = SyncAndConfigureReceived; @@ -2094,10 +2088,8 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event) m_mapped = true; if (m_deferredActivation) requestActivateWindow(); - if (m_configureNotifyPending) - m_deferredExpose = true; - else - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); + + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 41c4b4443d..43e66a774d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -231,8 +231,6 @@ protected: bool m_transparent; bool m_usingSyncProtocol; bool m_deferredActivation; - bool m_deferredExpose; - bool m_configureNotifyPending; bool m_embedded; bool m_alertState; xcb_window_t m_netWmUserTimeWindow; -- cgit v1.2.3 From c7251e7dcd624b8225a2f9b2f14e6f73d1c09a60 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 24 Nov 2015 10:39:49 +0100 Subject: Revert "Fix deadlock when setting environment variables." This reverts commit 5b62a5e7aabcc818408f2fe28b9760082f474def. This commit is reverted due to two reasons: 1) It was written incorrectly and does not work as is. The ifdefs should be ifndefs. In its current state, it does the exact opposite of what it is supposed to be doing. 2) There is another environment access inside qsimd.cpp (which checks QT_NO_CPU_FEATURE). This access causes the app to hang. All in all that approach is not sustainable as we might get bitten by environment access again and again. Instead we should use another environment container or use a recursive mutex for WinRT and Windows CE. Task-number: QTBUG-49529 Change-Id: Iaca76404dc1023551a7c25489a609681135765fd Reviewed-by: Andrew Knight Reviewed-by: Samuel Nevala --- src/corelib/tools/qhash.cpp | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index fe49e8c6a8..b334a697a9 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -38,14 +38,6 @@ #ifndef _CRT_RAND_S #define _CRT_RAND_S #endif - -// Windows Runtime and CE use a QHash to fake environment variables. To avoid -// deadlock, disable reading the QT_HASH_SEED environment variable within -// QHash. -#if defined(Q_OS_WINRT) || defined(Q_OS_WINCE) -# define QHASH_NO_ENV_SEED -#endif - #include #include "qhash.h" @@ -231,11 +223,9 @@ static uint qt_create_qhash_seed() uint seed = 0; #ifndef QT_BOOTSTRAPPED -#ifdef QHASH_NO_ENV_SEED QByteArray envSeed = qgetenv("QT_HASH_SEED"); if (!envSeed.isNull()) return envSeed.toUInt(); -#endif // QHASH_NO_ENV_SEED #ifdef Q_OS_UNIX int randomfd = qt_safe_open("/dev/urandom", O_RDONLY); @@ -337,10 +327,8 @@ int qGlobalQHashSeed() */ void qSetGlobalQHashSeed(int newSeed) { -#ifdef QHASH_NO_ENV_SEED if (qEnvironmentVariableIsSet("QT_HASH_SEED")) return; -#endif // QHASH_NO_ENV_SEED if (newSeed == -1) { int x(qt_create_qhash_seed() & INT_MAX); qt_qhash_seed.store(x); @@ -1194,9 +1182,6 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW decimal value, will be used as the seed for qHash(). Alternatively, you can call the qSetGlobalQHashSeed() function. - \note The environment variable \c QT_HASH_SEED is unsupported on Windows - Runtime and CE. Use qSetGlobalQHashSeed() instead on those platforms. - \sa QHashIterator, QMutableHashIterator, QMap, QSet */ -- cgit v1.2.3 From 5c7f000cd4c9e3769e8cd4085cf0beee104f9886 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 18 Nov 2015 15:20:14 +0100 Subject: Reduce the number of paint events for QOpenGLWidget Changes to other widgets in the window, especially special cases like moving dock widgets around, trigger an unfortunately high number of paint events and calls to paintGL(). Let's try to avoid this. There is no need to send out a paint event to a texture-backed widget when it was not explicitly dirtied. Overlaps won't matter since such widgets are not part of the backingstore. Everything else has to work like ordinary widgets, though, it is only the QPaintEvent sending we can optimize away, nothing else. Task-number: QTBUG-49466 Change-Id: I8ef294ba0a6c305d0002a80e85c06db2c2501cf8 Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qwidget.cpp | 13 ++++++++++--- src/widgets/kernel/qwidget_p.h | 3 +++ src/widgets/kernel/qwidgetbackingstore.cpp | 3 +++ 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 0d07eedc0b..94099aac7a 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -271,6 +271,9 @@ QWidgetPrivate::QWidgetPrivate(int version) #ifndef QT_NO_IM , inheritsInputMethodHints(0) #endif +#ifndef QT_NO_OPENGL + , renderToTextureReallyDirty(1) +#endif #if defined(Q_OS_WIN) , noPaintOnScreen(0) #endif @@ -5547,7 +5550,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP << "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size()); #endif - bool grabbed = false; + bool skipPaintEvent = false; #ifndef QT_NO_OPENGL if (renderToTexture) { // This widget renders into a texture which is composed later. We just need to @@ -5561,14 +5564,18 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP } else { // We are not drawing to a backingstore: fall back to QImage p.drawImage(q->rect(), grabFramebuffer()); - grabbed = true; + skipPaintEvent = true; } endBackingStorePainting(); } + if (renderToTextureReallyDirty) + renderToTextureReallyDirty = 0; + else + skipPaintEvent = true; } #endif // QT_NO_OPENGL - if (!grabbed) { + if (!skipPaintEvent) { //actually send the paint event sendPaintEvent(toBePainted); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index a78cf099ac..7eb8d048b3 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -743,6 +743,9 @@ public: #ifndef QT_NO_IM uint inheritsInputMethodHints : 1; #endif +#ifndef QT_NO_OPENGL + uint renderToTextureReallyDirty : 1; +#endif // *************************** Platform specific ************************************ #if defined(Q_OS_WIN) diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 9036c28b9a..6d43adc33b 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1230,6 +1230,9 @@ void QWidgetBackingStore::doSync() QWidget *w = static_cast(tl->source(i)); if (dirtyRenderToTextureWidgets.contains(w)) { const QRect rect = tl->geometry(i); // mapped to the tlw already + // Set a flag to indicate that the paint event for this + // render-to-texture widget must not to be optimized away. + w->d_func()->renderToTextureReallyDirty = 1; dirty += rect; toClean += rect; } -- cgit v1.2.3 From 68d100692b7175f62bdf1c9e5b899cec14d7e259 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Mon, 23 Nov 2015 15:10:46 +0100 Subject: Doc: added sample to QFileOpenEvent class details MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This sample will help user needing to react on QFileOpenEvent get started faster. Change-Id: I7def292894fc39d803f70cbf0453f6791b7aea15 Reviewed-by: Topi Reiniö --- src/gui/doc/snippets/qfileopenevent/Info.plist | 59 +++++++++++++++++++++ src/gui/doc/snippets/qfileopenevent/main.cpp | 73 ++++++++++++++++++++++++++ src/gui/kernel/qevent.cpp | 15 ++++++ 3 files changed, 147 insertions(+) create mode 100644 src/gui/doc/snippets/qfileopenevent/Info.plist create mode 100644 src/gui/doc/snippets/qfileopenevent/main.cpp (limited to 'src') diff --git a/src/gui/doc/snippets/qfileopenevent/Info.plist b/src/gui/doc/snippets/qfileopenevent/Info.plist new file mode 100644 index 0000000000..6b8039bc7d --- /dev/null +++ b/src/gui/doc/snippets/qfileopenevent/Info.plist @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Samuel Gaist +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [Custom Info.plist] + + + + + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + png + + CFBundleTypeRole + Viewer + + + + +//! [Custom Info.plist] \ No newline at end of file diff --git a/src/gui/doc/snippets/qfileopenevent/main.cpp b/src/gui/doc/snippets/qfileopenevent/main.cpp new file mode 100644 index 0000000000..3fd1757bd7 --- /dev/null +++ b/src/gui/doc/snippets/qfileopenevent/main.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Samuel Gaist +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [QApplication subclass] +#include +#include +#include + +class MyApplication : public QApplication +{ +public: + MyApplication(int &argc, char **argv) + : QApplication(argc, argv) + { + } + + bool event(QEvent *event) + { + if (event->type() == QEvent::FileOpen) { + QFileOpenEvent *openEvent = static_cast(event); + qDebug() << "Open file" << openEvent->file(); + } + + return QApplication::event(event); + } +}; +//! [QApplication subclass] + +int main(int argc, char *argv[]) +{ + MyApplication app(argc, argv); + QPushButton closeButton("Quit"); + QObject::connect(&closeButton, &QPushButton::clicked, &app, &QApplication::quit); + closeButton.show(); + return app.exec(); +} diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 0bb21752bc..2ca17692db 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3417,6 +3417,21 @@ QShowEvent::~QShowEvent() It may be safely ignored. \note This class is currently supported for OS X only. + + \section1 OS X Example + + In order to trigger the event on OS X, the application must be configured + to let the OS know what kind of file(s) it should react on. + + For example, the following \c Info.plist file declares that the application + can act as a viewer for files with a PNG extension: + + \snippet qfileopenevent/Info.plist Custom Info.plist + + The following implementation of a QApplication subclass prints the path to + the file that was, for example, dropped on the Dock icon of the application. + + \snippet qfileopenevent/main.cpp QApplication subclass */ /*! -- cgit v1.2.3 From 2277e3b873ed2dc687ff49b0fc83f38c512748a1 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 20 Nov 2015 10:27:40 +0100 Subject: Proof-reading fixes to QCoreApplication documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Things I noticed while reading - so I fixed them. Change-Id: I48f6f2eef7ac3cf901e2f1305c503fb18f5ab2ae Reviewed-by: Topi Reiniö --- src/corelib/kernel/qcoreapplication.cpp | 41 +++++++++++++++++---------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index a2a7eed064..aa44d2e74b 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -625,7 +625,7 @@ void QCoreApplicationPrivate::initLocale() \section1 The Event Loop and Event Handling - The event loop is started with a call to exec(). Long running + The event loop is started with a call to exec(). Long-running operations can call processEvents() to keep the application responsive. @@ -707,7 +707,7 @@ QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p) #ifndef QT_NO_QOBJECT /*! - Flushes the platform specific event queues. + Flushes the platform-specific event queues. If you are doing graphical changes inside a loop that does not return to the event loop on asynchronous window systems like X11 @@ -725,9 +725,9 @@ void QCoreApplication::flush() #endif /*! - Constructs a Qt kernel application. Kernel applications are - applications without a graphical user interface. These type of - applications are used at the console or as server processes. + Constructs a Qt core application. Core applications are applications without + a graphical user interface. Such applications are used at the console or as + server processes. The \a argc and \a argv arguments are processed by the application, and made available in a more convenient form by the arguments() @@ -1209,7 +1209,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags) milliseconds or until there are no more events to process, whichever is shorter. - You can call this function occasionally when you program is busy + You can call this function occasionally when your program is busy doing a long operation (e.g. copying a file). Calling this function processes events only for the calling thread. @@ -1236,9 +1236,9 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m *****************************************************************************/ /*! - Enters the main event loop and waits until exit() is called. - Returns the value that was set to exit() (which is 0 if exit() is - called via quit()). + Enters the main event loop and waits until exit() is called. Returns + the value that was passed to exit() (which is 0 if exit() is called via + quit()). It is necessary to call this function to start event handling. The main event loop receives events from the window system and @@ -1494,7 +1494,8 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven If \a receiver is null, the events of \a event_type are sent for all objects. If \a event_type is 0, all the events are sent for \a receiver. - \note This method must be called from the same thread as its QObject parameter, \a receiver. + \note This method must be called from the thread in which its QObject + parameter, \a receiver, lives. \sa flush(), postEvent() */ @@ -1840,7 +1841,7 @@ void QCoreApplication::quit() This signal is emitted when the application is about to quit the main event loop, e.g. when the event loop level drops to zero. This may happen either after a call to quit() from inside the - application or when the users shuts down the entire desktop session. + application or when the user shuts down the entire desktop session. The signal is particularly useful if your application has to do some last-second cleanup. Note that no user interaction is possible in @@ -2070,8 +2071,8 @@ void QCoreApplicationPrivate::setApplicationFilePath(const QString &path) directory, and you run the \c{regexp} example, this function will return "C:/Qt/examples/tools/regexp". - On OS X and iOS this will point to the directory actually containing the - executable, which may be inside of an application bundle (if the + On OS X and iOS this will point to the directory actually containing + the executable, which may be inside an application bundle (if the application is bundled). \warning On Linux, this function will try to get the path from the @@ -2684,11 +2685,11 @@ void QCoreApplication::removeLibraryPath(const QString &path) The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function, which is called for all native events received in the main thread. - The QAbstractNativeEventFilter::nativeEventFilter() function should return true if the event should - be filtered, (i.e. stopped). It should return false to allow - normal Qt processing to continue: the native event can then be translated - into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering, - e.g. QObject::installEventFilter(). + The QAbstractNativeEventFilter::nativeEventFilter() function should + return true if the event should be filtered, i.e. stopped. It should + return false to allow normal Qt processing to continue: the native + event can then be translated into a QEvent and handled by the standard + Qt \l{QEvent} {event} filtering, e.g. QObject::installEventFilter(). If multiple event filters are installed, the filter that was installed last is activated first. @@ -2696,7 +2697,7 @@ void QCoreApplication::removeLibraryPath(const QString &path) \note The filter function set here receives native messages, i.e. MSG or XCB event structs. - \note Native event filters will be disabled when the application the + \note Native event filters will be disabled in the application when the Qt::AA_MacPluginApplication attribute is set. For maximum portability, you should always try to use QEvent @@ -2885,7 +2886,7 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc \snippet code/src_corelib_kernel_qcoreapplication.cpp 7 The \a context parameter is normally the class name, but it can - be any string. + be any text. \sa Q_OBJECT, QObject::tr(), QObject::trUtf8() */ -- cgit v1.2.3 From d06d7413d5ac22e2c0d65e3144e80da6c716f9f5 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 25 Nov 2015 11:16:12 +0100 Subject: Fix QTextLine::cursorToX() 0e99f3c broke tst_qquicktextinput::horizontalAlignment_RightToLeft() and tst_qquicktextedit::hAlign_RightToLeft(). This fix was proposed by Konstantin. Change-Id: I602b7301d415f266224ae2c1ffd81244e9565862 Reviewed-by: Simon Hausmann Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 5f570fea82..65650504ac 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2627,7 +2627,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const const QScriptLine &line = eng->lines[index]; bool lastLine = index >= eng->lines.size() - 1; - QFixed x = line.x; + QFixed x = line.x + eng->alignLine(line) - eng->leadingSpaceWidth(line); if (!eng->layoutData) eng->itemize(); @@ -2636,8 +2636,6 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const return x.toReal(); } - x += eng->alignLine(line) - eng->leadingSpaceWidth(line); - int lineEnd = line.from + line.length + line.trailingSpaces; int pos = qBound(line.from, *cursorPos, lineEnd); int itm; -- cgit v1.2.3 From 9c430bc4c925ca61bc32c39fe0cfb1952553f501 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 25 Nov 2015 09:14:04 +0100 Subject: QSignalSpy: Improve warning about unregistered parameter types. Don't know how to handle 'hint', use qRegisterMetaType to register it. becomes: QSignalSpy: Unable to handle parameter 'hint' of type 'QAbstractItemModel::LayoutChangeHint' of method 'layoutChanged', use qRegisterMetaType to register it. Task-number: QTBUG-49623 Change-Id: I5020bb5b6f4ba87438d0f862279bed1ceb203d12 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/testlib/qsignalspy.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/testlib/qsignalspy.h b/src/testlib/qsignalspy.h index 1751220059..e9744d0b07 100644 --- a/src/testlib/qsignalspy.h +++ b/src/testlib/qsignalspy.h @@ -175,8 +175,11 @@ private: tp = QMetaType::UnknownType; } if (tp == QMetaType::UnknownType) { - qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.", - member.parameterNames().at(i).constData()); + qWarning("QSignalSpy: Unable to handle parameter '%s' of type '%s' of method '%s'," + " use qRegisterMetaType to register it.", + member.parameterNames().at(i).constData(), + member.parameterTypes().at(i).constData(), + member.name().constData()); } args << tp; } -- cgit v1.2.3 From 9b28fd5bfcedef16e2f4c59124f0628670f96556 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 24 Nov 2015 14:30:10 +0100 Subject: Fix inplaceRgbConversion test on non-x86 We test that inline conversion between same image depths always succeed inline, but that requires that any direct conversions exists both in non-inline and inline versions. This patch adds a non-sse2 inline conversion from ARGB32 to ARGB32PM which was missing. Change-Id: I71937cd4b77fb41fe2064da937f6dcbf2a6534e6 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage_conversions.cpp | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 02f32aa34b..8e0e53c58d 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -375,7 +375,32 @@ static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::I } } +#ifdef __SSE2__ extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags); +#else +static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data,Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888); + + const int pad = (data->bytes_per_line >> 2) - data->width; + QRgb *rgb_data = (QRgb *) data->data; + + for (int i = 0; i < data->height; ++i) { + const QRgb *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = qPremultiply(*rgb_data); + ++rgb_data; + } + rgb_data += pad; + } + + if (data->format == QImage::Format_ARGB32) + data->format = QImage::Format_ARGB32_Premultiplied; + else + data->format = QImage::Format_RGBA8888_Premultiplied; + return true; +} +#endif static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { @@ -2592,7 +2617,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma #ifdef __SSE2__ convert_ARGB_to_ARGB_PM_inplace_sse2, #else - 0, + convert_ARGB_to_ARGB_PM_inplace, #endif 0, 0, @@ -2705,12 +2730,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, mask_alpha_converter_rgbx_inplace, -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && __SSE2__ 0, +#ifdef __SSE2__ convert_ARGB_to_ARGB_PM_inplace_sse2, +#elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN + convert_ARGB_to_ARGB_PM_inplace, #else 0, - 0, #endif 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888 -- cgit v1.2.3 From 980f8aed32403527e2922c2c671bbe29a6911c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 19 Oct 2015 14:11:28 +0200 Subject: iOS: Add support for delivering touch pressure on iPhone 6s/6s+ devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As 3D touch can be disabled/enabled at runtime on those devices, we need to watch for changes to the relevant settings and update the touch device capabilities that we report to the user. Note that iOS will deliver touchesBegan with a touch force of 0, which we will reflect/propagate as a 0 pressure, but there is no clear alternative, as we don't want to wait for a touchedMoved before sending a touch press event to Qt, just to have a valid pressure. Change-Id: I47fb8a9f98ab3244e16a337bbfcf1fe24e4c7aa2 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.mm | 10 +++++++--- src/plugins/platforms/ios/quiview.mm | 29 +++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index eaff0daf19..0e3da8dce8 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -89,10 +89,11 @@ QIOSIntegration::QIOSIntegration() // Set current directory to app bundle folder QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String])); + UIScreen *mainScreen = [UIScreen mainScreen]; NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease]; - if (![screens containsObject:[UIScreen mainScreen]]) { + if (![screens containsObject:mainScreen]) { // Fallback for iOS 7.1 (QTBUG-42345) - [screens insertObject:[UIScreen mainScreen] atIndex:0]; + [screens insertObject:mainScreen atIndex:0]; } for (UIScreen *screen in screens) @@ -103,7 +104,10 @@ QIOSIntegration::QIOSIntegration() m_touchDevice = new QTouchDevice; m_touchDevice->setType(QTouchDevice::TouchScreen); - m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); + QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition; + if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) + touchCapabilities |= QTouchDevice::Pressure; + m_touchDevice->setCapabilities(touchCapabilities); QWindowSystemInterface::registerTouchDevice(m_touchDevice); QMacInternalPasteboardMime::initializeMimeTypes(); } diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index c6ef843b9f..53b3d30327 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -280,6 +280,19 @@ // ------------------------------------------------------------------------- +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection +{ + [super traitCollectionDidChange: previousTraitCollection]; + + QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice(); + QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities(); + if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) + touchCapabilities |= QTouchDevice::Pressure; + else + touchCapabilities &= ~QTouchDevice::Pressure; + touchDevice->setCapabilities(touchCapabilities); +} + -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput) @@ -289,6 +302,8 @@ - (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state { + bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QTouchDevice::Pressure; + foreach (UITouch *uiTouch, m_activeTouches.keys()) { QWindowSystemInterface::TouchPoint &touchPoint = m_activeTouches[uiTouch]; if (![touches containsObject:uiTouch]) { @@ -309,9 +324,17 @@ touchPoint.normalPosition = QPointF(globalScreenPosition.x() / screenSize.width(), globalScreenPosition.y() / screenSize.height()); - // We don't claim that our touch device supports QTouchDevice::Pressure, - // but fill in a meaningfull value in case clients use it anyways. - touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0; + if (supportsPressure) { + // Note: iOS will deliver touchesBegan with a touch force of 0, which + // we will reflect/propagate as a 0 pressure, but there is no clear + // alternative, as we don't want to wait for a touchedMoved before + // sending a touch press event to Qt, just to have a valid pressure. + touchPoint.pressure = uiTouch.force / uiTouch.maximumPossibleForce; + } else { + // We don't claim that our touch device supports QTouchDevice::Pressure, + // but fill in a meaningfull value in case clients use it anyways. + touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0; + } } } } -- cgit v1.2.3 From 79447068579ea93d616d840bb8cbbf8adb1ed6ec Mon Sep 17 00:00:00 2001 From: Nicolas Capens Date: Tue, 10 Nov 2015 00:03:34 -0500 Subject: Fix potential division by zero. In a Chrome Remote Desktop session the htotal and/or vtotal timings can be zero and lead to a SIGFPE exception. Task-number: QTBUG-49322 Change-Id: Id530335cc760d1938ed888ad095427fcf32c651d Reviewed-by: Oswald Buddenhagen Reviewed-by: Nicolas Capens Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbscreen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 2a53b18890..0e99d58679 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -558,7 +558,8 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode) for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) { xcb_randr_mode_info_t *modeInfo = modesIter.data; if (modeInfo->id == mode) { - m_refreshRate = modeInfo->dot_clock / (modeInfo->htotal * modeInfo->vtotal); + const uint32_t dotCount = modeInfo->htotal * modeInfo->vtotal; + m_refreshRate = (dotCount != 0) ? modeInfo->dot_clock / dotCount : 0; m_mode = mode; break; } -- cgit v1.2.3 From 07fdfa559844403d0836ab0783f201b50a9961af Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 12 Nov 2015 15:50:00 +0100 Subject: Detect NEON on AArch64 The __ARM_NEON is the standard define for NEON instructions support __ARM_NEON__ is only legacy, and specifically not defined in AArch64 builds, which causes us not to detect NEON support there. The NEON assembler files doesn't build with AArch64, so the NEON drawhelper methods must be excluded for now. Change-Id: Ie32f855bde94ee7efd8a8ddb7766c931778e729b Reviewed-by: Thiago Macieira --- src/corelib/tools/qsimd_p.h | 6 +++++- src/gui/painting/painting.pri | 2 +- src/gui/painting/qdrawhelper.cpp | 4 ++-- src/gui/painting/qdrawhelper_neon.cpp | 4 +--- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 1e8b3420cf..12a329f36c 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -250,9 +250,13 @@ // NEON intrinsics // note: as of GCC 4.9, does not support function targets for ARM -#if defined __ARM_NEON__ +#if defined(__ARM_NEON) || defined(__ARM_NEON__) #include #define QT_FUNCTION_TARGET_STRING_ARM_NEON "neon" +#ifndef __ARM_NEON__ +// __ARM_NEON__ is not defined on AArch64, but we need it in our NEON detection. +#define __ARM_NEON__ +#endif #endif #undef QT_COMPILER_SUPPORTS_SIMD_ALWAYS diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 2e2532a25f..fd9ae0aaca 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -101,7 +101,7 @@ SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \ painting/qimagescale_sse4.cpp AVX2_SOURCES += painting/qdrawhelper_avx2.cpp -!ios { +!ios:!contains(QT_ARCH, "arm64") { CONFIG += no_clang_integrated_as NEON_SOURCES += painting/qdrawhelper_neon.cpp NEON_HEADERS += painting/qdrawhelper_neon_p.h diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 52843fa113..988bee9b27 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6309,7 +6309,7 @@ void qt_memfill16(quint16 *dest, quint16 color, int count) qt_memfill_template(dest, color, count); } #endif -#if !defined(__SSE2__) && !defined(__ARM_NEON__) +#if !defined(__SSE2__) && (!defined(__ARM_NEON__) || defined(Q_PROCESSOR_ARM_64)) # ifdef QT_COMPILER_SUPPORTS_MIPS_DSP extern "C" void qt_memfill32_asm_mips_dsp(quint32 *, quint32, int); # endif @@ -6425,7 +6425,7 @@ void qInitDrawhelperAsm() #endif // SSE2 -#if defined(__ARM_NEON__) && !defined(Q_OS_IOS) +#if defined(__ARM_NEON__) && !defined(Q_OS_IOS) && !defined(Q_PROCESSOR_ARM_64) qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 08e564f017..bf4758afd2 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -31,15 +31,13 @@ ** ****************************************************************************/ -#include +#include #include #include #ifdef __ARM_NEON__ -#include #include -#include QT_BEGIN_NAMESPACE -- cgit v1.2.3 From acc3df2c4e65fac822fc0f69d9849f1996130741 Mon Sep 17 00:00:00 2001 From: Ilya Kotov Date: Sun, 22 Nov 2015 13:05:38 +0300 Subject: Send QEvent::Tooltip to QSystemTrayIcon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QSystemTrayIcon's window should send QEvent::ToolTip to QSystemTrayIcon main class under X11. This patch fixes regression inroduced in Qt 5.0. Change-Id: I81f6d85e13f492e5e7d13dacc44185a511e5085d Task-number: QTBUG-46130 Reviewed-by: Błażej Szczygieł Reviewed-by: Laszlo Agocs --- src/widgets/util/qsystemtrayicon.cpp | 6 ------ src/widgets/util/qsystemtrayicon_x11.cpp | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index d22791048f..31bbbb9739 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -284,12 +284,6 @@ bool QSystemTrayIcon::isVisible() const */ bool QSystemTrayIcon::event(QEvent *e) { -#if defined(Q_DEAD_CODE_FROM_QT4_X11) - if (e->type() == QEvent::ToolTip) { - Q_D(QSystemTrayIcon); - return d->sys->deliverToolTipEvent(e); - } -#endif return QObject::event(e); } diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index 9a69db1bc8..02bab236c8 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -194,6 +194,9 @@ void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev) bool QSystemTrayIconSys::event(QEvent *e) { switch (e->type()) { + case QEvent::ToolTip: + QApplication::sendEvent(q, e); + break; #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: return QApplication::sendEvent(q, e); -- cgit v1.2.3 From 45470e71bcfefba577739a56ddecd0b1e9b97d5d Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Tue, 24 Nov 2015 11:47:19 +0100 Subject: Remove O(n^2) behavior in fallbacksForFamily(). Speeds up application startup by a few percent, even with just a normal amount of fonts installed. Change-Id: I4c3d87119ddbc53e66166f21cb72946cdf7e4a41 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Konstantin Ritt --- .../fontdatabases/fontconfig/qfontconfigdatabase.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 0af9440b50..a5fe88871d 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -716,15 +716,19 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont FcPatternDestroy(pattern); if (fontSet) { + QSet duplicates; + duplicates.reserve(fontSet->nfont + 1); + duplicates.insert(family.toCaseFolded()); for (int i = 0; i < fontSet->nfont; i++) { FcChar8 *value = 0; if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch) continue; // capitalize(value); - QString familyName = QString::fromUtf8((const char *)value); - if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) && - familyName.compare(family, Qt::CaseInsensitive)) { + const QString familyName = QString::fromUtf8((const char *)value); + const QString familyNameCF = familyName.toCaseFolded(); + if (!duplicates.contains(familyNameCF)) { fallbackFamilies << familyName; + duplicates.insert(familyNameCF); } } FcFontSetDestroy(fontSet); -- cgit v1.2.3 From 4a4b17805c976b40a404b48ba51984c9abdba633 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Tue, 24 Nov 2015 21:00:38 +0100 Subject: Fix QCOMPARE with enum classes. As these are strongly typed, they won't implicitly convert to int, so make sure to cast explicitly. (cherry picked from commit 9626baaea98edc13236250fc4b92d461b80e3875, auto test is not included) Task-number: QTBUG-49597 Change-Id: I29c4331a9b0c61f2e60c2bcab5a99f65daa7060f Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/testlib/qtestcase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 7d2fd2e701..9d79439e04 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -238,7 +238,7 @@ namespace QTest inline typename QtPrivate::QEnableIf::Value, char*>::Type toString(T e) { QMetaEnum me = QMetaEnum::fromType(); - return qstrdup(me.key(e)); + return qstrdup(me.key(int(e))); // int cast is necessary to support enum classes } template // Fallback -- cgit v1.2.3 From 7cbbca586092944eab0f024e0c249044b7599c24 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 24 Nov 2015 14:32:53 +0100 Subject: Add AArch64 ASM to qimage_neon.cpp Since AArch64 NEON assembly is different from Arm32 NEON we need to write a separate version. Assembly is used over intrinsics as the intrinsics have trouble efficiently using the vstX and vldX instructions. Change-Id: I5b67fc87acb2433b503e658099b742d57a9cff18 Reviewed-by: Erik Verbruggen --- src/gui/image/qimage_conversions.cpp | 2 +- src/gui/image/qimage_neon.cpp | 30 ++++++++++++++++++++++++++++-- src/gui/image/qjpeghandler.cpp | 3 +-- 3 files changed, 30 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 8e0e53c58d..7d1fb23b15 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -2947,7 +2947,7 @@ void qInitImageConversions() } #endif -#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64) +#if defined(__ARM_NEON__) extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon; qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon; diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp index b51c43aa9d..5853510ee1 100644 --- a/src/gui/image/qimage_neon.cpp +++ b/src/gui/image/qimage_neon.cpp @@ -35,7 +35,7 @@ #include #include -#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64) +#if defined(__ARM_NEON__) QT_BEGIN_NAMESPACE @@ -55,6 +55,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons if ((len - offsetToAlignOn8Bytes) >= 8) { const quint32 *const simdEnd = end - 7; +#if !defined(Q_PROCESSOR_ARM_64) register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff); do { #if Q_BYTE_ORDER == Q_BIG_ENDIAN @@ -76,6 +77,31 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons ); #endif } while (dst < simdEnd); +#else + register uint8x8_t fullVector asm ("v3") = vdup_n_u8(0xff); + do { +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + asm volatile ( + "ld3 { v4.8b, v5.8b, v6.8b }, [%[SRC]], #24 \n\t" + "st4 { v3.8b, v4.8b, v5.8b, v6.8b }, [%[DST]], #32 \n\t" + : [DST]"+r" (dst), [SRC]"+r" (src) + : "w"(fullVector) + : "memory", "v4", "v5", "v6" + ); +#else + asm volatile ( + "ld3 { v0.8b, v1.8b, v2.8b }, [%[SRC]], #24 \n\t" + "mov v4.8b, v2.8b\n\t" + "mov v2.8b, v0.8b\n\t" + "mov v0.8b, v4.8b\n\t" + "st4 { v0.8b, v1.8b, v2.8b, v3.8b }, [%[DST]], #32 \n\t" + : [DST]"+r" (dst), [SRC]"+r" (src) + : "w"(fullVector) + : "memory", "v0", "v1", "v2", "v4" + ); +#endif + } while (dst < simdEnd); +#endif } while (dst != end) { @@ -103,4 +129,4 @@ void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::I QT_END_NAMESPACE -#endif // defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64) +#endif // defined(__ARM_NEON__) diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 7e9483e6f7..68709b708d 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -978,9 +978,8 @@ extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uc QJpegHandler::QJpegHandler() : d(new QJpegHandlerPrivate(this)) { -#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64) +#if defined(__ARM_NEON__) // from qimage_neon.cpp - if (qCpuHasFeature(NEON)) d->rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon; #endif -- cgit v1.2.3 From b13801fd550d4eef2e45ac3e11304571e0146dd9 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 25 Nov 2015 13:44:37 +0100 Subject: Avoid pulling in X11 headers in brcm backend In some configurations we may end up using Mesa's EGL headers instead of the Broadcom ones. Make this work by setting the usual define to prevent including Xlib headers that then conflict with all sorts of things in QtCore. Change-Id: I4970553428e5b0e81bd76694980f3b6b194ae4c2 Reviewed-by: Andy Nichols --- .../platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro index 98797e2106..2026b6a6c6 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro @@ -12,6 +12,9 @@ CONFIG += egl LIBS += -lbcm_host QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF +# Avoid X11 header collision +DEFINES += MESA_EGL_NO_X11_HEADERS + SOURCES += $$PWD/qeglfsbrcmmain.cpp \ $$PWD/qeglfsbrcmintegration.cpp -- cgit v1.2.3