From e5078714febaa72bf2f43b3a8ac9caec1c324129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20=C3=96lmann?= Date: Mon, 14 Oct 2019 12:12:24 +0200 Subject: qlibinputtouch: bugfix: do not skip touch events Having a platform with Texas Instruments's ADS7846 touch screen controller (NXP i.MX6 DualLite SoC) and a LOGIC Technologies Inc. LTTD800x480 L2RT 7" (800x480 pixels) TFT LCD panel attached to it (resistive touch) using Linux v5.2.17 and libinput-1.12.6 a single one finger touch starts with a LIBINPUT_EVENT_TOUCH_ DOWN directly followed by a LIBINPUT_EVENT_TOUCH_MOTION both having the same touch position. Now Qt's code for touch input processing compressed both into one touch point with state Qt::TouchPointStationary which resulted in QGuiApplicationPrivate:: processTouchEvent() seeing no touch points with state Qt::TouchPointPressed anymore. As a consequence processTouchEvent()'s local container windowsNeeding- Events stayed empty and the whole touch frame was skipped. Fix this by still compressing into one touch point, but keeping its state as Qt::TouchPointPressed. Fixes: QTBUG-79212 Change-Id: Ia571d79ec5c1d6143e923ed69b378503b53e5992 Reviewed-by: Shawn Rutledge Reviewed-by: Laszlo Agocs --- src/platformsupport/input/libinput/qlibinputtouch.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/platformsupport/input/libinput/qlibinputtouch.cpp b/src/platformsupport/input/libinput/qlibinputtouch.cpp index a65bc91c39..ad85360b0e 100644 --- a/src/platformsupport/input/libinput/qlibinputtouch.cpp +++ b/src/platformsupport/input/libinput/qlibinputtouch.cpp @@ -113,16 +113,16 @@ void QLibInputTouch::processTouchMotion(libinput_event_touch *e) DeviceState *state = deviceState(e); QWindowSystemInterface::TouchPoint *tp = state->point(slot); if (tp) { + Qt::TouchPointState tmpState = Qt::TouchPointMoved; const QPointF p = getPos(e); - if (tp->area.center() != p) { + if (tp->area.center() == p) + tmpState = Qt::TouchPointStationary; + else tp->area.moveCenter(p); - // 'down' may be followed by 'motion' within the same "frame". - // Handle this by compressing and keeping the Pressed state until the 'frame'. - if (tp->state != Qt::TouchPointPressed) - tp->state = Qt::TouchPointMoved; - } else { - tp->state = Qt::TouchPointStationary; - } + // 'down' may be followed by 'motion' within the same "frame". + // Handle this by compressing and keeping the Pressed state until the 'frame'. + if (tp->state != Qt::TouchPointPressed && tp->state != Qt::TouchPointReleased) + tp->state = tmpState; } else { qWarning("Inconsistent touch state (got 'motion' without 'down')"); } -- cgit v1.2.3 From 5771b5325b85f71a8f8ff78ed13eaee3df2e3ba8 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 5 Nov 2019 22:10:24 +0100 Subject: syncqt: Add a means to suspend/resume the processing of a file Rather than tweaking the parser to cover every eventuality with corner case lines that could cause incorrect header files to be created then the means to suspend/resume the processing of a file is added. This enables us to have it skip over the template line that is causing a QList header to be created as part of the QtGui headers. This patch includes the fix to solve this in addition. Fixes: QTBUG-68129 Change-Id: I751646c4b20a4434347c149ae5e6dcb6e7618853 Reviewed-by: Joerg Bornemann --- bin/syncqt.pl | 5 ++++- src/gui/kernel/qevent.h | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/bin/syncqt.pl b/bin/syncqt.pl index 8226edfb76..11ae5845eb 100755 --- a/bin/syncqt.pl +++ b/bin/syncqt.pl @@ -212,6 +212,7 @@ sub classNames { $$clean = 1; $$requires = ""; + my $suspended = 0; my $ihdrbase = basename($iheader); my $parsable = ""; @@ -224,9 +225,11 @@ sub classNames { $$clean = 0 if ($line =~ m/^#pragma qt_sync_skip_header_check/); return @ret if($line =~ m/^#pragma qt_sync_stop_processing/); push(@ret, $1) if($line =~ m/^#pragma qt_class\(([^)]*)\)[\r\n]*$/); + $suspended = 1 if ($line =~ m/^#pragma qt_sync_suspend_processing/); + $suspended = 0 if ($line =~ m/^#pragma qt_sync_resume_processing/); $line = 0; } - if($line) { + if ($line && !$suspended) { $line =~ s,//.*$,,; #remove c++ comments $line .= ";" if($line =~ m/^Q_[A-Z_0-9]*\(.*\)[\r\n]*$/); #qt macro $line .= ";" if($line =~ m/^QT_(BEGIN|END)_HEADER[\r\n]*$/); #qt macro diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 2b1c6a6e31..0a8a1925e7 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -827,7 +827,14 @@ private: qint64 m_numericId; }; Q_DECLARE_TYPEINFO(QPointingDeviceUniqueId, Q_MOVABLE_TYPE); + +#if 0 +#pragma qt_sync_suspend_processing +#endif template <> class QList {}; // to prevent instantiation: use QVector instead +#if 0 +#pragma qt_sync_resume_processing +#endif Q_GUI_EXPORT bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW; inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW -- cgit v1.2.3 From 78ed3a12dbae70232711fd704e549ea0595ddd95 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 6 Nov 2019 14:31:23 +0100 Subject: Fix typo in QLoggingCategory documentation Change-Id: Id147e6f4c25a75eed5456390819f340d8d20172c Reviewed-by: Jesus Fernandez --- src/corelib/io/qloggingcategory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 89607d5a98..4a83780234 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -179,7 +179,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) The \c QtProject/qtlogging.ini file is looked up in all directories returned by QStandardPaths::GenericConfigLocation. - Set the \c QT_LOGGING_DEBUG environment variable to find out where you logging + Set the \c QT_LOGGING_DEBUG environment variable to find out where your logging rules are loaded from. \section2 Installing a Custom Filter -- cgit v1.2.3 From 3916b8a28bc9c55e10f4de611ed76e17017494aa Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 24 Oct 2019 08:34:46 +0200 Subject: iOS: Account for UITextInteraction when building against 12.x or lower MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In iOS 13.0 we can handle UITextInteraction as normal, but in lower versions it is not available to utilize at compile time. So we have to check for the other types instead and return if it is not one of those. Change-Id: Icbc5558e677ed40c03f30a174e2d79b87f489f68 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/quiview.mm | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 4e3657ec37..91a186bace 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -628,17 +628,13 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") #endif } -#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(130000) - (void)addInteraction:(id)interaction { - if (__builtin_available(iOS 13.0, *)) { - if ([interaction isKindOfClass:UITextInteraction.class]) - return; // Prevent iOS from adding UITextInteraction - } + if ([NSStringFromClass(interaction.class) isEqualToString:@"UITextInteraction"]) + return; [super addInteraction:interaction]; } -#endif @end -- cgit v1.2.3 From ef54abae43db79792b40dfdca30ac0fa1b582354 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 29 Oct 2019 20:42:00 +0100 Subject: Windows QPA: Fix missing update when the display is sleeping If an item was updated while the display was in sleep mode then when the display came back from sleep it would not be updated. This change detects when the display returns from sleep and repaints the windows to ensure the updated items are presented. Fixes: QTBUG-76307 Change-Id: I5fff5209e8a5c359d06ba1df61944690e9475ea6 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowscontext.cpp | 58 ++++++++++++++++++++++ src/plugins/platforms/windows/qwindowscontext.h | 2 + .../platforms/windows/qwindowsintegration.cpp | 2 + 3 files changed, 62 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 38b9823d6b..5c1b00a1c9 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -273,6 +273,8 @@ struct QWindowsContextPrivate { const HRESULT m_oleInitializeResult; QWindow *m_lastActiveWindow = nullptr; bool m_asyncExpose = false; + HPOWERNOTIFY m_powerNotification = nullptr; + HWND m_powerDummyWindow = nullptr; }; QWindowsContextPrivate::QWindowsContextPrivate() @@ -313,6 +315,13 @@ QWindowsContext::~QWindowsContext() #if QT_CONFIG(tabletevent) d->m_tabletSupport.reset(); // Destroy internal window before unregistering classes. #endif + + if (d->m_powerNotification) + UnregisterPowerSettingNotification(d->m_powerNotification); + + if (d->m_powerDummyWindow) + DestroyWindow(d->m_powerDummyWindow); + unregisterWindowClasses(); if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) OleUninitialize(); @@ -380,6 +389,55 @@ bool QWindowsContext::initPointer(unsigned integrationOptions) return true; } +extern "C" LRESULT QT_WIN_CALLBACK qWindowsPowerWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message != WM_POWERBROADCAST || wParam != PBT_POWERSETTINGCHANGE) + return DefWindowProc(hwnd, message, wParam, lParam); + + static bool initialized = false; // ignore the initial change + if (!initialized) { + initialized = true; + return DefWindowProc(hwnd, message, wParam, lParam); + } + + auto setting = reinterpret_cast(lParam); + if (setting) { + auto data = reinterpret_cast(&setting->Data); + if (*data == 1) { + // Repaint the windows when returning from sleeping display mode. + const auto tlw = QGuiApplication::topLevelWindows(); + for (auto w : tlw) { + if (w->isVisible() && w->windowState() != Qt::WindowMinimized) { + if (auto tw = QWindowsWindow::windowsWindowOf(w)) { + if (HWND hwnd = tw->handle()) { + InvalidateRect(hwnd, nullptr, false); + } + } + } + } + } + } + return DefWindowProc(hwnd, message, wParam, lParam); +} + +bool QWindowsContext::initPowerNotificationHandler() +{ + if (d->m_powerNotification) + return false; + + d->m_powerDummyWindow = createDummyWindow(QStringLiteral("QtPowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc); + if (!d->m_powerDummyWindow) + return false; + + d->m_powerNotification = RegisterPowerSettingNotification(d->m_powerDummyWindow, &GUID_MONITOR_POWER_ON, DEVICE_NOTIFY_WINDOW_HANDLE); + if (!d->m_powerNotification) { + DestroyWindow(d->m_powerDummyWindow); + d->m_powerDummyWindow = nullptr; + return false; + } + return true; +} + void QWindowsContext::setTabletAbsoluteRange(int a) { #if QT_CONFIG(tabletevent) diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 4908f14629..04290379db 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -176,6 +176,8 @@ public: bool initTablet(unsigned integrationOptions); bool initPointer(unsigned integrationOptions); + bool initPowerNotificationHandler(); + int defaultDPI() const; QString registerWindowClass(const QWindow *w); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 5c1fa00088..849e6cf2d0 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -256,6 +256,8 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL m_context.initTouch(m_options); QPlatformCursor::setCapability(QPlatformCursor::OverrideCursor); + + m_context.initPowerNotificationHandler(); } QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() -- cgit v1.2.3 From 26f8adb1eefd1a8822413e036f2878b8cc1e7029 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Thu, 7 Nov 2019 16:52:10 +0100 Subject: Windows QPA: Avoid returning UI Automation ValueProvider for static text Static text controls should not return a ValueProvider. Otherwise, Narrator reads out static texts and announces whether they are editable or not, which is confusing to users. It should only read out the text itself. Fixes: QTBUG-79613 Change-Id: I080cd6a5db10f6f673b50c40ac7d87c3737d9b55 Reviewed-by: Friedemann Kleint --- .../platforms/windows/uiautomation/qwindowsuiamainprovider.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index 5a05adbf81..96d64acc32 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -277,8 +277,9 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow } break; case UIA_ValuePatternId: - // All accessible controls return text(QAccessible::Value) (which may be empty). - *pRetVal = new QWindowsUiaValueProvider(id()); + // All non-static controls support the Value pattern. + if (accessible->role() != QAccessible::StaticText) + *pRetVal = new QWindowsUiaValueProvider(id()); break; case UIA_RangeValuePatternId: // Controls providing a numeric value within a range (e.g., sliders, scroll bars, dials). -- cgit v1.2.3 From 1dd83dd202eccf0d68b6dd0b2c2155a7cc3018d2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 8 Nov 2019 10:48:43 +0100 Subject: Diaglib/Windows: Output more information on geometry for native handles Obtain the client area and output frame and position relative to the parent window. Task-number: QTBUG-79861 Change-Id: I193dfbcdec7e27d32a70ada08ba271260eedc969 Reviewed-by: Andy Shaw --- tests/manual/diaglib/nativewindowdump_win.cpp | 71 +++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/tests/manual/diaglib/nativewindowdump_win.cpp b/tests/manual/diaglib/nativewindowdump_win.cpp index aae8746413..d91e673d1c 100644 --- a/tests/manual/diaglib/nativewindowdump_win.cpp +++ b/tests/manual/diaglib/nativewindowdump_win.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -54,14 +55,76 @@ struct DumpContext { if (style & styleConstant) \ str << ' ' << #styleConstant; +static QTextStream &operator<<(QTextStream &str, const QPoint &p) +{ + str << p.x() << ", " << p.y(); + return str; +} + +static QTextStream &operator<<(QTextStream &str, const QSize &s) +{ + str << s.width() << 'x' << s.height(); + return str; +} + +static QTextStream &operator<<(QTextStream &str, const QRect &rect) +{ + str << rect.size() << forcesign << rect.x() << rect.y() << noforcesign; + return str; +} + +static inline QSize qsizeFromRECT(const RECT &rect) +{ + return QSize(rect.right -rect.left, rect.bottom - rect.top); +} + +static inline QRect qrectFromRECT(const RECT &rect) +{ + return QRect(QPoint(rect.left, rect.top), qsizeFromRECT(rect)); +} + +static QRect getFrameGeometry(HWND hwnd) +{ + RECT rect; + return GetWindowRect(hwnd, &rect) ? qrectFromRECT(rect) : QRect(); +} + +static QPoint getClientAreaScreenPos(HWND hwnd) +{ + POINT clientPos{0, 0}; + return ClientToScreen(hwnd, &clientPos) ? QPoint(clientPos.x, clientPos.y) : QPoint(); +} + +static QRect getClientAreaGeometry(HWND hwnd) +{ + RECT clientRect; + return GetClientRect(hwnd, &clientRect) + ? QRect(getClientAreaScreenPos(hwnd), qsizeFromRECT(clientRect)) : QRect(); +} + +static bool isTopLevel(HWND hwnd) +{ + auto parent = GetParent(hwnd); + return !parent || parent == GetDesktopWindow(); +} + static void formatNativeWindow(HWND hwnd, QTextStream &str) { str << hex << showbase << quintptr(hwnd) << noshowbase << dec; - RECT rect; - if (GetWindowRect(hwnd, &rect)) { - str << ' ' << (rect.right - rect.left) << 'x' << (rect.bottom - rect.top) - << forcesign << rect.left << rect.top << noforcesign; + + const bool topLevel = isTopLevel(hwnd); + if (topLevel) + str << " [top]"; + const auto frameGeometry = getFrameGeometry(hwnd); + const auto clientGeometry = getClientAreaGeometry(hwnd); + str << ' ' << frameGeometry; + if (!topLevel) + str << " local: " << (clientGeometry.topLeft() - getClientAreaScreenPos(GetParent(hwnd))); + if (clientGeometry != frameGeometry) { + str << " client: " << clientGeometry << " frame: " + << (clientGeometry.topLeft() - frameGeometry.topLeft()); } + if (IsWindowVisible(hwnd)) str << " [visible]"; -- cgit v1.2.3 From 8f2db974ab594125301aac62594510e146125cb4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 1 Nov 2019 11:15:32 +0100 Subject: Windows QPA: Fix wrong scaling of fixed size in window creation phase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a fixed size the window is moved to another screen by QPlatformWindow::initialGeometry(), the size constraints would be incorrectly scaled using the initial screen in the handling of WM_GETMINMAXINFO. To fix this, pass the resulting screen out of QPlatformWindow::initialGeometry() and use it during the window creation phase. Fixes: QTBUG-77307 Change-Id: I149a2a65e816da841a32abc14a495925bf9cc6f6 Reviewed-by: André de la Rocha Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qplatformwindow.cpp | 9 ++++-- src/gui/kernel/qplatformwindow.h | 6 ++-- src/plugins/platforms/windows/qwindowswindow.cpp | 35 +++++++++++++++++------- src/plugins/platforms/windows/qwindowswindow.h | 10 +++++-- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 2a0cb1094c..65accc9f68 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -694,9 +694,12 @@ static QSize fixInitialSize(QSize size, const QWindow *w, However if the given window already has geometry which the application has initialized, it takes priority. */ -QRect QPlatformWindow::initialGeometry(const QWindow *w, - const QRect &initialGeometry, int defaultWidth, int defaultHeight) +QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry, + int defaultWidth, int defaultHeight, + const QScreen **resultingScreenReturn) { + if (resultingScreenReturn) + *resultingScreenReturn = w->screen(); if (!w->isTopLevel()) { const qreal factor = QHighDpiScaling::factor(w); const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), @@ -712,6 +715,8 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, : QGuiApplication::screenAt(initialGeometry.center()); if (!screen) return initialGeometry; + if (resultingScreenReturn) + *resultingScreenReturn = screen; // initialGeometry refers to window's screen QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); if (wp->resizeAutomatic) diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 4d48cc2f13..b6aeb3a86a 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE class QPlatformScreen; class QPlatformWindowPrivate; +class QScreen; class QWindow; class QIcon; class QRegion; @@ -142,8 +143,9 @@ public: virtual void invalidateSurface(); - static QRect initialGeometry(const QWindow *w, - const QRect &initialGeometry, int defaultWidth, int defaultHeight); + static QRect initialGeometry(const QWindow *w, const QRect &initialGeometry, + int defaultWidth, int defaultHeight, + const QScreen **resultingScreenReturn = nullptr); virtual void requestUpdate(); bool hasPendingUpdateRequest() const; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index a4f4099aa6..ea91e3bb2d 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -759,7 +759,10 @@ QWindowsWindowData const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w); - const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, defaultWindowWidth, defaultWindowHeight); + const QScreen *screen{}; + const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, + defaultWindowWidth, defaultWindowHeight, + &screen); if (title.isEmpty() && (result.flags & Qt::WindowTitleHint)) title = topLevel ? qAppName() : w->objectName(); @@ -769,7 +772,9 @@ QWindowsWindowData // Capture events before CreateWindowEx() returns. The context is cleared in // the QWindowsWindow constructor. - const QWindowCreationContextPtr context(new QWindowCreationContext(w, data.geometry, rect, data.customMargins, style, exStyle)); + const QWindowCreationContextPtr context(new QWindowCreationContext(w, screen, data.geometry, + rect, data.customMargins, + style, exStyle)); QWindowsContext::instance()->setWindowCreationContext(context); const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME)); @@ -879,10 +884,10 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang // Scaling helpers for size constraints. -static QSize toNativeSizeConstrained(QSize dip, const QWindow *w) +static QSize toNativeSizeConstrained(QSize dip, const QScreen *s) { if (QHighDpiScaling::isActive()) { - const qreal factor = QHighDpiScaling::factor(w); + const qreal factor = QHighDpiScaling::factor(s); if (!qFuzzyCompare(factor, qreal(1))) { if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX) dip.setWidth(qRound(qreal(dip.width()) * factor)); @@ -995,11 +1000,12 @@ bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, co return true; } -void QWindowsGeometryHint::frameSizeConstraints(const QWindow *w, const QMargins &margins, +void QWindowsGeometryHint::frameSizeConstraints(const QWindow *w, const QScreen *screen, + const QMargins &margins, QSize *minimumSize, QSize *maximumSize) { - *minimumSize = toNativeSizeConstrained(w->minimumSize(), w); - *maximumSize = toNativeSizeConstrained(w->maximumSize(), w); + *minimumSize = toNativeSizeConstrained(w->minimumSize(), screen); + *maximumSize = toNativeSizeConstrained(w->maximumSize(), screen); const int maximumWidth = qMax(maximumSize->width(), minimumSize->width()); const int maximumHeight = qMax(maximumSize->height(), minimumSize->height()); @@ -1017,12 +1023,13 @@ void QWindowsGeometryHint::frameSizeConstraints(const QWindow *w, const QMargins } void QWindowsGeometryHint::applyToMinMaxInfo(const QWindow *w, + const QScreen *screen, const QMargins &margins, MINMAXINFO *mmi) { QSize minimumSize; QSize maximumSize; - frameSizeConstraints(w, margins, &minimumSize, &maximumSize); + frameSizeConstraints(w, screen, margins, &minimumSize, &maximumSize); qCDebug(lcQpaWindows).nospace() << '>' << __FUNCTION__ << '<' << " min=" << minimumSize.width() << ',' << minimumSize.height() << " max=" << maximumSize.width() << ',' << maximumSize.height() @@ -1041,6 +1048,13 @@ void QWindowsGeometryHint::applyToMinMaxInfo(const QWindow *w, qCDebug(lcQpaWindows).nospace() << '<' << __FUNCTION__ << " out " << *mmi; } +void QWindowsGeometryHint::applyToMinMaxInfo(const QWindow *w, + const QMargins &margins, + MINMAXINFO *mmi) +{ + applyToMinMaxInfo(w, w->screen(), margins, mmi); +} + bool QWindowsGeometryHint::positionIncludesFrame(const QWindow *w) { return qt_window_private(const_cast(w))->positionPolicy @@ -1226,11 +1240,12 @@ void QWindowsForeignWindow::setVisible(bool visible) \ingroup qt-lighthouse-win */ -QWindowCreationContext::QWindowCreationContext(const QWindow *w, +QWindowCreationContext::QWindowCreationContext(const QWindow *w, const QScreen *s, const QRect &geometryIn, const QRect &geometry, const QMargins &cm, DWORD style, DWORD exStyle) : window(w), + screen(s), requestedGeometryIn(geometryIn), requestedGeometry(geometry), obtainedPos(geometryIn.topLeft()), @@ -1270,7 +1285,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, void QWindowCreationContext::applyToMinMaxInfo(MINMAXINFO *mmi) const { - QWindowsGeometryHint::applyToMinMaxInfo(window, margins + customMargins, mmi); + QWindowsGeometryHint::applyToMinMaxInfo(window, screen, margins + customMargins, mmi); } /*! diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 7efbcf900c..1f8800272b 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -66,9 +66,12 @@ struct QWindowsGeometryHint static QMargins frame(const QWindow *w, const QRect &geometry, DWORD style, DWORD exStyle); static bool handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result); + static void applyToMinMaxInfo(const QWindow *w, const QScreen *screen, + const QMargins &margins, MINMAXINFO *mmi); static void applyToMinMaxInfo(const QWindow *w, const QMargins &margins, MINMAXINFO *mmi); - static void frameSizeConstraints(const QWindow *w, const QMargins &margins, + static void frameSizeConstraints(const QWindow *w, const QScreen *screen, + const QMargins &margins, QSize *minimumSize, QSize *maximumSize); static inline QPoint mapToGlobal(HWND hwnd, const QPoint &); static inline QPoint mapToGlobal(const QWindow *w, const QPoint &); @@ -80,13 +83,16 @@ struct QWindowsGeometryHint struct QWindowCreationContext { - explicit QWindowCreationContext(const QWindow *w, + explicit QWindowCreationContext(const QWindow *w, const QScreen *s, const QRect &geometryIn, const QRect &geometry, const QMargins &customMargins, DWORD style, DWORD exStyle); void applyToMinMaxInfo(MINMAXINFO *mmi) const; const QWindow *window; + // The screen to use to scale size constraints, etc. Might differ from the + // screen of the window after QPlatformWindow::initialGeometry() (QTBUG-77307). + const QScreen *screen; QRect requestedGeometryIn; // QWindow scaled QRect requestedGeometry; // after QPlatformWindow::initialGeometry() QPoint obtainedPos; -- cgit v1.2.3 From 8ffb200153d1b1a8402c875c4961160efb149201 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 6 Nov 2019 11:23:12 +0100 Subject: Fix LTCG linker flags for macOS with separate debug info The linker must not throw away the lto.o file. We now instruct the linker to create a non-temporary lto.o, dependent on the target name. In order to do that we introduce a new mkspec variable QMAKE_LFLAGS_LTCG_SEPARATE_DEBUG_INFO. This variable can contain single-$ variable references that get evaluated when loading ltcg.prf. Fixes: QTBUG-72846 Change-Id: I0ea882628d63e5406ba0ee68c7435af597364b0f Reviewed-by: Alexandru Croitor Reviewed-by: Edward Welbourne Reviewed-by: Kai Koehne --- mkspecs/common/clang-mac.conf | 1 + mkspecs/features/ltcg.prf | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/mkspecs/common/clang-mac.conf b/mkspecs/common/clang-mac.conf index cbae2e6262..143406308c 100644 --- a/mkspecs/common/clang-mac.conf +++ b/mkspecs/common/clang-mac.conf @@ -5,6 +5,7 @@ QMAKE_OBJCXXFLAGS_PRECOMPILE = -x objective-c++-header -c ${QMAKE_PCH_INPUT} QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvm.clang.1_0 +QMAKE_LFLAGS_LTCG_SEPARATE_DEBUG_INFO = -Wl,-object_path_lto,${OBJECTS_DIR}/${TARGET}_lto.o QMAKE_CXXFLAGS += -stdlib=libc++ QMAKE_LFLAGS += -stdlib=libc++ diff --git a/mkspecs/features/ltcg.prf b/mkspecs/features/ltcg.prf index a94f6d0eeb..5fa6309016 100644 --- a/mkspecs/features/ltcg.prf +++ b/mkspecs/features/ltcg.prf @@ -1,6 +1,12 @@ static:no-static-ltcg { # Static library but no-static-ltcg enabled: skip LTCG } else: CONFIG(release, debug|release) { + separate_debug_info { + # Evaluate single-$ variable references that have no valid value at mkspec loading time + QMAKE_LFLAGS_LTCG_SEPARATE_DEBUG_INFO ~= s/\\$\\{/\$\$\{/ + eval(QMAKE_LFLAGS_LTCG += $$QMAKE_LFLAGS_LTCG_SEPARATE_DEBUG_INFO) + } + # We need fat object files when creating static libraries on some platforms # so the linker will know to load a particular object from the library # in the first place. On others, we have special ar and nm to create the symbol -- cgit v1.2.3 From bf131e8d2181b3404f5293546ed390999f760404 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 8 Nov 2019 11:30:40 +0100 Subject: Do not load plugin from the $PWD I see no reason why this would make sense to look for plugins in the current directory. And when there are plugins there, it may actually be wrong Change-Id: I5f5aa168021fedddafce90effde0d5762cd0c4c5 Reviewed-by: Thiago Macieira --- src/corelib/plugin/qpluginloader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index cadff4f32b..c2443dbdda 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -305,7 +305,6 @@ static QString locatePlugin(const QString& fileName) paths.append(fileName.left(slash)); // don't include the '/' } else { paths = QCoreApplication::libraryPaths(); - paths.prepend(QStringLiteral(".")); // search in current dir first } for (const QString &path : qAsConst(paths)) { -- cgit v1.2.3 From aef07a433f16f5ed3800ee60e11116f78f13d3c4 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 27 Sep 2019 16:27:58 +0200 Subject: QTableWidget: Fix -Wdeprecated-copy warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In file included from ../../include/QtCore/qlist.h:1, from ../../include/QtCore/../../../qtbase_dev_de_verdad/src/corelib/kernel/qobject.h:49, from ../../include/QtCore/qobject.h:1, from ../../include/QtCore/../../../qtbase_dev_de_verdad/src/corelib/kernel/qcoreapplication.h:46, from ../../include/QtCore/qcoreapplication.h:1, from /src/widgets/kernel/../../gui/kernel/../../corelib/global/qt_pch.h:66, from /src/widgets/kernel/../../gui/kernel/qt_gui_pch.h:48, from /src/widgets/kernel/qt_widgets_pch.h:48: ../../include/QtCore/../../../qtbase_dev_de_verdad/src/corelib/tools/qlist.h: In instantiation of ‘void QList::node_construct(QList::Node*, const T&) [with T = QTableWidgetSelectionRange]’: ../../include/QtCore/../../../qtbase_dev_de_verdad/src/corelib/tools/qlist.h:614:13: required from ‘void QList::append(const T&) [with T = QTableWidgetSelectionRange]’ /src/widgets/itemviews/qtablewidget.cpp:2416:71: required from here ../../include/QtCore/../../../qtbase_dev_de_verdad/src/corelib/tools/qlist.h:471:35: warning: implicitly-declared ‘constexpr QTableWidgetSelectionRange& QTableWidgetSelectionRange::operator=(const QTableWidgetSelectionRange&)’ is deprecated [-Wdeprecated-copy] 471 | else *reinterpret_cast(n) = t; | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ In file included from /src/widgets/itemviews/qtablewidget.cpp:40: /src/widgets/itemviews/qtablewidget.h:52:24: note: because ‘QTableWidgetSelectionRange’ has user-provided ‘QTableWidgetSelectionRange::QTableWidgetSelectionRange(const QTableWidgetSelectionRange&)’ 52 | class Q_WIDGETS_EXPORT QTableWidgetSelectionRange | ^~~~~~~~~~~~~~~~~~~~~~~~~~ Change-Id: Iad959315ad374ef288f5fffd15d6876cb63bce8e Reviewed-by: Christian Ehrlicher Reviewed-by: Friedemann Kleint Reviewed-by: Volker Hilsheimer (cherry picked from commit 127ed7e6e0f8939861cce7349e28a1dec9a7d6ed) --- src/widgets/itemviews/qtablewidget.cpp | 6 ++---- src/widgets/itemviews/qtablewidget.h | 5 ++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index a25a582881..b1dbafa997 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -923,10 +923,8 @@ QTableWidgetSelectionRange::QTableWidgetSelectionRange(int top, int left, int bo Constructs a the table selection range by copying the given \a other table selection range. */ -QTableWidgetSelectionRange::QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other) - : top(other.top), left(other.left), bottom(other.bottom), right(other.right) -{ -} +QTableWidgetSelectionRange::QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other) = default; +QTableWidgetSelectionRange &QTableWidgetSelectionRange::operator=(const QTableWidgetSelectionRange &other) = default; /*! Destroys the table selection range. diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h index d93032f3f0..0d93a0a075 100644 --- a/src/widgets/itemviews/qtablewidget.h +++ b/src/widgets/itemviews/qtablewidget.h @@ -49,14 +49,17 @@ QT_REQUIRE_CONFIG(tablewidget); QT_BEGIN_NAMESPACE +// ### Qt6 unexport the class, remove the user-defined special 3 and make it a literal type. class Q_WIDGETS_EXPORT QTableWidgetSelectionRange { public: QTableWidgetSelectionRange(); QTableWidgetSelectionRange(int top, int left, int bottom, int right); - QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other); ~QTableWidgetSelectionRange(); + QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other); + QTableWidgetSelectionRange &operator=(const QTableWidgetSelectionRange &other); + inline int topRow() const { return top; } inline int bottomRow() const { return bottom; } inline int leftColumn() const { return left; } -- cgit v1.2.3 From 30f4ca4e4fbc1d8cf86808dbeb00ec3c046f6c1c Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 14 Feb 2019 04:06:27 +1000 Subject: wasm: fix building examples and applications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a bug where app build would fail with AssertionError: SIMD is used, but not supported in WASM mode yet This patch was wiped out by the recent freetype update and is exactly the same as 44b91a619d14932635e9a3fe155de4df9f98a25c Fixes: QTBUG-79938 Change-Id: Iaa8f23c83d0488ddd351454a674a6cad76e7cc8b Reviewed-by: Edward Welbourne Reviewed-by: Liang Qi Reviewed-by: Morten Johan Sørvig --- src/3rdparty/freetype/src/sfnt/pngshim.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/3rdparty/freetype/src/sfnt/pngshim.c b/src/3rdparty/freetype/src/sfnt/pngshim.c index ca85d9751f..fc78b6d5df 100644 --- a/src/3rdparty/freetype/src/sfnt/pngshim.c +++ b/src/3rdparty/freetype/src/sfnt/pngshim.c @@ -68,6 +68,7 @@ ( ( __clang_major__ >= 4 ) || \ ( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 2 ) ) ) ) ) && \ defined( __OPTIMIZE__ ) && \ + !defined( __EMSCRIPTEN__ ) && \ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #ifdef __clang__ -- cgit v1.2.3 From 364160600889d6055a556a189e6f3d4a8dc3f96d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 8 Nov 2019 14:02:01 +0100 Subject: Use default QTD font size for mono font when importing markdown QFontDatabase::systemFont(FixedFont) determines the font for inline code and code blocks in a markdown document. Now we change the size of that font to the same size as QTextDocument::defaultFont() so that the user has the ability to customize the font size in each document instead of only system-wide. Change-Id: Ief7367336f7613e88695dbb08bcb7e9f50db8961 Reviewed-by: Shawn Rutledge --- src/gui/text/qtextmarkdownimporter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp index c2ad1e5612..78d18a714b 100644 --- a/src/gui/text/qtextmarkdownimporter.cpp +++ b/src/gui/text/qtextmarkdownimporter.cpp @@ -160,6 +160,10 @@ void QTextMarkdownImporter::import(QTextDocument *doc, const QString &markdown) m_paragraphMargin = m_doc->defaultFont().pointSize() * 2 / 3; m_cursor = new QTextCursor(doc); doc->clear(); + if (doc->defaultFont().pointSize() != -1) + m_monoFont.setPointSize(doc->defaultFont().pointSize()); + else + m_monoFont.setPixelSize(doc->defaultFont().pixelSize()); qCDebug(lcMD) << "default font" << doc->defaultFont() << "mono font" << m_monoFont; QByteArray md = markdown.toUtf8(); md_parse(md.constData(), MD_SIZE(md.size()), &callbacks, this); -- cgit v1.2.3 From 17b8a49fded383ffff1bd8552b55e8b5c01b2ecc Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 12 Nov 2019 14:22:26 +0100 Subject: Move some tests of QTimeZonePrivate::isValidId() to where they belong They were tucked away in the back-end of the isTimeZoneIdAvailable() test, but a separate isValidId() test had been added more recently, which made some (arguably all) of them redundant. Reworked this test in the process, so that the QSKIP() happens in _data() once instead of in the test that's never run because there are no data rows. Change-Id: Icaa6227ace9a1aa944d085691cdcfb3adf4a51dc Reviewed-by: Thiago Macieira --- .../auto/corelib/time/qtimezone/tst_qtimezone.cpp | 52 ++++++++++------------ 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp index 9904719f7c..9f51ff8ba8 100644 --- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -377,31 +377,6 @@ void tst_QTimeZone::isTimeZoneIdAvailable() QList available = QTimeZone::availableTimeZoneIds(); foreach (const QByteArray &id, available) QVERIFY(QTimeZone::isTimeZoneIdAvailable(id)); - -#ifdef QT_BUILD_INTERNAL - // a-z, A-Z, 0-9, '.', '-', '_' are valid chars - // Can't start with '-' - // Parts separated by '/', each part min 1 and max of 14 chars - QCOMPARE(QTimeZonePrivate::isValidId("az"), true); - QCOMPARE(QTimeZonePrivate::isValidId("AZ"), true); - QCOMPARE(QTimeZonePrivate::isValidId("09"), true); - QCOMPARE(QTimeZonePrivate::isValidId("a/z"), true); - QCOMPARE(QTimeZonePrivate::isValidId("a.z"), true); - QCOMPARE(QTimeZonePrivate::isValidId("a-z"), true); - QCOMPARE(QTimeZonePrivate::isValidId("a_z"), true); - QCOMPARE(QTimeZonePrivate::isValidId(".z"), true); - QCOMPARE(QTimeZonePrivate::isValidId("_z"), true); - QCOMPARE(QTimeZonePrivate::isValidId("12345678901234"), true); - QCOMPARE(QTimeZonePrivate::isValidId("12345678901234/12345678901234"), true); - QCOMPARE(QTimeZonePrivate::isValidId("a z"), false); - QCOMPARE(QTimeZonePrivate::isValidId("a\\z"), false); - QCOMPARE(QTimeZonePrivate::isValidId("a,z"), false); - QCOMPARE(QTimeZonePrivate::isValidId("/z"), false); - QCOMPARE(QTimeZonePrivate::isValidId("-z"), false); - QCOMPARE(QTimeZonePrivate::isValidId("123456789012345"), false); - QCOMPARE(QTimeZonePrivate::isValidId("123456789012345/12345678901234"), false); - QCOMPARE(QTimeZonePrivate::isValidId("12345678901234/123456789012345"), false); -#endif // QT_BUILD_INTERNAL } void tst_QTimeZone::specificTransition_data() @@ -728,6 +703,9 @@ void tst_QTimeZone::isValidId_data() QTest::addColumn("input"); QTest::addColumn("valid"); + // a-z, A-Z, 0-9, '.', '-', '_' are valid chars + // Can't start with '-' + // Parts separated by '/', each part min 1 and max of 14 chars #define TESTSET(name, section, valid) \ QTest::newRow(name " front") << QByteArray(section "/xyz/xyz") << valid; \ QTest::newRow(name " middle") << QByteArray("xyz/" section "/xyz") << valid; \ @@ -766,6 +744,26 @@ void tst_QTimeZone::isValidId_data() TESTSET("invalid char ' '", " ", false); #undef TESTSET + + QTest::newRow("az alone") << QByteArray("az") << true; + QTest::newRow("AZ alone") << QByteArray("AZ") << true; + QTest::newRow("09 alone") << QByteArray("09") << true; + QTest::newRow("a/z alone") << QByteArray("a/z") << true; + QTest::newRow("a.z alone") << QByteArray("a.z") << true; + QTest::newRow("a-z alone") << QByteArray("a-z") << true; + QTest::newRow("a_z alone") << QByteArray("a_z") << true; + QTest::newRow(".z alone") << QByteArray(".z") << true; + QTest::newRow("_z alone") << QByteArray("_z") << true; + QTest::newRow("a z alone") << QByteArray("a z") << false; + QTest::newRow("a\\z alone") << QByteArray("a\\z") << false; + QTest::newRow("a,z alone") << QByteArray("a,z") << false; + QTest::newRow("/z alone") << QByteArray("/z") << false; + QTest::newRow("-z alone") << QByteArray("-z") << false; + QTest::newRow("long alone") << QByteArray("12345678901234") << true; + QTest::newRow("over-long alone") << QByteArray("123456789012345") << false; + +#else + QSKIP("This test requires a Qt -developer-build."); #endif // QT_BUILD_INTERNAL } @@ -776,8 +774,6 @@ void tst_QTimeZone::isValidId() QFETCH(bool, valid); QCOMPARE(QTimeZonePrivate::isValidId(input), valid); -#else - QSKIP("This test requires a Qt -developer-build."); #endif } -- cgit v1.2.3 From 6961d46b6e07fc9492c31e5bd8b98660fd65e4e6 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 7 Oct 2019 15:48:41 +0200 Subject: Fuzzing: Add comment how to recude noise in iccparser's fuzzer With logging enabled, all the output will slow down execution and fill up your hard disc in about a day. Task-number: QTBUG-79050 Change-Id: I5dcac2f349f7dbe471a5e6dd7006b89d312aeeaf Reviewed-by: Eirik Aavitsland --- tests/libfuzzer/gui/iccparser/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/libfuzzer/gui/iccparser/main.cpp b/tests/libfuzzer/gui/iccparser/main.cpp index 1db43d2e25..7681c1468e 100644 --- a/tests/libfuzzer/gui/iccparser/main.cpp +++ b/tests/libfuzzer/gui/iccparser/main.cpp @@ -29,6 +29,10 @@ #include #include +// Run this with +// QT_LOGGING_RULES="qt.gui.icc=false" +// to reduce noise and increase speed. + extern "C" int LLVMFuzzerTestOneInput(const char *data, size_t size) { static int c = 0; static QGuiApplication a(c, nullptr); -- cgit v1.2.3 From 491005395b08660ff12a167b57a2d76e26917145 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 12 Nov 2019 17:06:57 +0100 Subject: configure.pri: improve error message when Android NDK host is invalid Old: ERROR: Specified Android NDK host is invalid. New: ERROR: Specified Android NDK host 'windows-x86_64' is invalid. Expected files in the following directory to exist: /foo/bar/toolchains/llvm/prebuilt/windows-x86_64/ Change-Id: Idd964cc0eeedfbd984b13dc9289830e6be766326 Reviewed-by: Eskil Abrahamsen Blomfeldt --- configure.pri | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure.pri b/configure.pri index 97b9f3bf63..2b8d20d607 100644 --- a/configure.pri +++ b/configure.pri @@ -607,8 +607,11 @@ defineTest(qtConfOutput_prepareOptions) { qtConfAddNote("Available Android host does not match host architecture.") } } else { - !exists($$ndk_tc_pfx/$$ndk_host/*): \ - qtConfFatalError("Specified Android NDK host is invalid.") + !exists($$ndk_tc_pfx/$$ndk_host/*) { + err = "Specified Android NDK host '$$ndk_host' is invalid. Expected files in the following directory to exist:" + err += '$${ndk_tc_pfx}/$${ndk_host}/' + qtConfFatalError($$err) + } } android_abis = $$eval(config.input.android-abis) -- cgit v1.2.3 From 2735c5bf069bcadefc2d6b626161e1166c2a683b Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 23 Oct 2019 07:48:04 +0200 Subject: Add support for passing qrc files to qmlimportscanner With the qrcFiles entry in the deployment JSON for Android, it can now pass this on to qmlimportscanner for scanning the qrc files for the available imports. This enables qmake to populate the qrc files it has referenced in the project, be it generated by qmake or added by the user. Task-number: QTBUG-55259 Change-Id: Ic512ce6f24508b3ea09ebdd07ac4446debfd9155 Reviewed-by: Joerg Bornemann --- .../android/android_deployment_settings.prf | 16 ++++++++++ src/tools/androiddeployqt/main.cpp | 35 ++++++++++++++-------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf index 4d6101e297..e781eb024c 100644 --- a/mkspecs/features/android/android_deployment_settings.prf +++ b/mkspecs/features/android/android_deployment_settings.prf @@ -63,6 +63,22 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded { QML_ROOT_PATH = $$_PRO_FILE_PWD_ FILE_CONTENT += " \"qml-root-path\": $$emitString($$QML_ROOT_PATH)," FILE_CONTENT += " \"stdcpp-path\": $$emitString($$ANDROID_STDCPP_PATH)," + !isEmpty(RESOURCES) { + # Make sure that qmake generated qrc files are accounted for + load(resources_functions) + qtFlattenResources() + for(resource, RESOURCES) { + contains(resource, ".*\\qmake_qmake_immediate.qrc$") { + # They will be created for each architecture, since they could be different + # we need to account for all of them + for (arch, ANDROID_ABIS): \ + rescopy += $$absolute_path("qmake_qmake_immediate.qrc", $$OUT_PWD/$$arch) + } else { + contains(resource, ".*\\.qrc$"): rescopy += $$absolute_path($$resource, $$_PRO_FILE_PWD_) + } + } + FILE_CONTENT += " \"qrcFiles\": $$emitString($$join(rescopy, ","))," + } FILE_CONTENT += "" FILE_CONTENT += " \"application-binary\": $$emitString($$TARGET)" FILE_CONTENT += "}" diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index feecfba8fb..550ed0832f 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -164,6 +164,7 @@ struct Options QString applicationBinary; QString rootPath; QStringList qmlImportPaths; + QStringList qrcFiles; // Versioning QString versionName; @@ -976,7 +977,10 @@ bool readInputFile(Options *options) } } } - + { + const QJsonValue qrcFiles = jsonObject.value(QLatin1String("qrcFiles")); + options->qrcFiles = qrcFiles.toString().split(QLatin1Char(','), QString::SkipEmptyParts); + } options->packageName = packageNameFromAndroidManifest(options->androidSourceDirectory + QLatin1String("/AndroidManifest.xml")); if (options->packageName.isEmpty()) options->packageName = cleanPackageName(QLatin1String("org.qtproject.example.%1").arg(options->applicationBinary)); @@ -1709,22 +1713,28 @@ bool scanImports(Options *options, QSet *usedDependencies) } QString rootPath = options->rootPath; - if (rootPath.isEmpty()) - rootPath = QFileInfo(options->inputFileName).absolutePath(); - else - rootPath = QFileInfo(rootPath).absoluteFilePath(); + if (!options->qrcFiles.isEmpty()) { + qmlImportScanner += QLatin1String(" -qrcFiles"); + for (const QString &qrcFile : options->qrcFiles) + qmlImportScanner += QLatin1Char(' ') + shellQuote(qrcFile); + } else { + if (rootPath.isEmpty()) + rootPath = QFileInfo(options->inputFileName).absolutePath(); + else + rootPath = QFileInfo(rootPath).absoluteFilePath(); - if (!rootPath.endsWith(QLatin1Char('/'))) - rootPath += QLatin1Char('/'); + if (!rootPath.endsWith(QLatin1Char('/'))) + rootPath += QLatin1Char('/'); + qmlImportScanner += QLatin1String(" -rootPath %1").arg(shellQuote(rootPath)); + } QStringList importPaths; importPaths += shellQuote(options->qtInstallDirectory + QLatin1String("/qml")); - importPaths += shellQuote(rootPath); + if (!rootPath.isEmpty()) + importPaths += shellQuote(rootPath); for (const QString &qmlImportPath : qAsConst(options->qmlImportPaths)) importPaths += shellQuote(qmlImportPath); - - qmlImportScanner += QLatin1String(" -rootPath %1 -importPath %2") - .arg(shellQuote(rootPath), importPaths.join(QLatin1Char(' '))); + qmlImportScanner += QLatin1String(" -importPath %1").arg(importPaths.join(QLatin1Char(' '))); if (options->verbose) { fprintf(stdout, "Running qmlimportscanner with the following command: %s\n", @@ -1946,7 +1956,8 @@ bool readDependencies(Options *options) } } - if (!options->rootPath.isEmpty() && !scanImports(options, &usedDependencies)) + if ((!options->rootPath.isEmpty() || options->qrcFiles.isEmpty()) && + !scanImports(options, &usedDependencies)) return false; return true; -- cgit v1.2.3 From 51cbd5288c85cb4de382cb23d6f5559c2b626126 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 8 Nov 2019 14:48:23 +0100 Subject: Fix rendering of markdown in QLabel Since 65314b6ce88cdbb28a22be0cab9856ec9bc9604b there is a TextFormat for MarkdownText, and QWidgetTextControl supports that, but QLabel does it in its own way and sets plain text or rich text on the text document itself. Add a code path for MarkdownText there. [ChangeLog][QtWidgets][QLabel] Markdown is now a supported textFormat for QLabel. Fixes: QTBUG-79766 Change-Id: Ib9370ef300089af2c4d6070e545c5470f32833a8 Reviewed-by: Shawn Rutledge --- src/widgets/widgets/qlabel.cpp | 33 ++++++++++++++++++++++----------- src/widgets/widgets/qlabel_p.h | 6 +++--- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index a840bf4ee6..77d117775a 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -85,6 +85,7 @@ QLabelPrivate::QLabelPrivate() shortcutId(0), #endif textformat(Qt::AutoText), + effectiveTextFormat(Qt::PlainText), textInteractionFlags(Qt::LinksAccessibleByMouse), sizePolicy(), margin(0), @@ -94,7 +95,6 @@ QLabelPrivate::QLabelPrivate() scaledcontents(false), textLayoutDirty(false), textDirty(false), - isRichText(false), isTextLabel(false), hasShortcut(/*???*/), #ifndef QT_NO_CURSOR @@ -294,8 +294,14 @@ void QLabel::setText(const QString &text) d->text = text; d->isTextLabel = true; d->textDirty = true; - d->isRichText = d->textformat == Qt::RichText - || (d->textformat == Qt::AutoText && Qt::mightBeRichText(d->text)); + if (d->textformat == Qt::AutoText) { + if (Qt::mightBeRichText(d->text)) + d->effectiveTextFormat = Qt::RichText; + else + d->effectiveTextFormat = Qt::PlainText; + } else { + d->effectiveTextFormat = d->textformat; + } d->control = oldControl; @@ -306,7 +312,7 @@ void QLabel::setText(const QString &text) d->control = nullptr; } - if (d->isRichText) { + if (d->effectiveTextFormat != Qt::PlainText) { setMouseTracking(true); } else { // Note: mouse tracking not disabled intentionally @@ -1478,14 +1484,19 @@ void QLabelPrivate::ensureTextPopulated() const if (control) { QTextDocument *doc = control->document(); if (textDirty) { -#ifndef QT_NO_TEXTHTMLPARSER - if (isRichText) - doc->setHtml(text); - else + if (effectiveTextFormat == Qt::PlainText) { doc->setPlainText(text); -#else - doc->setPlainText(text); +#if QT_CONFIG(texthtmlparser) + } else if (effectiveTextFormat == Qt::RichText) { + doc->setHtml(text); +#endif +#if QT_CONFIG(textmarkdownreader) + } else if (effectiveTextFormat == Qt::MarkdownText) { + doc->setMarkdown(text); #endif + } else { + doc->setPlainText(text); + } doc->setUndoRedoEnabled(false); #ifndef QT_NO_SHORTCUT @@ -1623,7 +1634,7 @@ QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos) { QString linkToCopy; QPoint p; - if (control && isRichText) { + if (control && effectiveTextFormat != Qt::PlainText) { p = layoutPoint(pos); linkToCopy = control->document()->documentLayout()->anchorAt(p); } diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h index 59188563a9..6b3fbc5f0c 100644 --- a/src/widgets/widgets/qlabel_p.h +++ b/src/widgets/widgets/qlabel_p.h @@ -93,8 +93,8 @@ public: #endif inline bool needTextControl() const { return isTextLabel - && (isRichText - || (!isRichText && (textInteractionFlags & (Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard)))); + && (effectiveTextFormat != Qt::PlainText + || (textInteractionFlags & (Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard))); } void ensureTextPopulated() const; @@ -134,6 +134,7 @@ public: int shortcutId; #endif Qt::TextFormat textformat; + Qt::TextFormat effectiveTextFormat; Qt::TextInteractionFlags textInteractionFlags; mutable QSizePolicy sizePolicy; int margin; @@ -143,7 +144,6 @@ public: uint scaledcontents : 1; mutable uint textLayoutDirty : 1; mutable uint textDirty : 1; - mutable uint isRichText : 1; mutable uint isTextLabel : 1; mutable uint hasShortcut : 1; #ifndef QT_NO_CURSOR -- cgit v1.2.3 From 103d307f2e596e5e7d2eb706117223bf65264e5f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 30 Sep 2019 12:00:43 -0700 Subject: Be explicit about QDataStream serialization: explicit casts to int The reader uses int variables, so use the same in the writer. Change-Id: I1496b069cc534f1a838dfffd15c94c7cacd3dd93 Reviewed-by: Laszlo Agocs --- src/gui/rhi/qshader.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/rhi/qshader.cpp b/src/gui/rhi/qshader.cpp index c22b029dc8..9d35d83336 100644 --- a/src/gui/rhi/qshader.cpp +++ b/src/gui/rhi/qshader.cpp @@ -348,10 +348,10 @@ void QShader::removeShader(const QShaderKey &key) static void writeShaderKey(QDataStream *ds, const QShaderKey &k) { - *ds << k.source(); + *ds << int(k.source()); *ds << k.sourceVersion().version(); *ds << k.sourceVersion().flags(); - *ds << k.sourceVariant(); + *ds << int(k.sourceVariant()); } /*! @@ -369,7 +369,7 @@ QByteArray QShader::serialized() const return QByteArray(); ds << QSB_VERSION; - ds << d->stage; + ds << int(d->stage); ds << d->desc.toBinaryJson(); ds << d->shaders.count(); for (auto it = d->shaders.cbegin(), itEnd = d->shaders.cend(); it != itEnd; ++it) { -- cgit v1.2.3 From ad11cab4842a4d35fe80641ae3eec7f2d8817652 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 10 Aug 2018 12:17:49 +0200 Subject: Allow longer time-zone components on Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Android uses its own time-zone naming, which includes a zone called "Canada/East-Saskatchewan", whose second component is 17 characters long. This violates a rule in the IANA naming scheme for zones, that limits components to 14 characters each. So tweak the isValidId() check to allow Android its long names. Android has added Outer Mongolian time-zones, which are as borked as many others in 1970, so blacklist those transitionEachZone() tests. Fixes: QTBUG-69128 Change-Id: I46f674f095431335b16900860d83b624257ae3bb Reviewed-by: Jan Arve Sæther --- src/corelib/time/qtimezoneprivate.cpp | 6 ++++++ tests/auto/corelib/time/qtimezone/BLACKLIST | 12 ++++++++---- tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp | 11 +++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp index 569b343187..00dc8b4ced 100644 --- a/src/corelib/time/qtimezoneprivate.cpp +++ b/src/corelib/time/qtimezoneprivate.cpp @@ -632,7 +632,13 @@ bool QTimeZonePrivate::isValidId(const QByteArray &ianaId) // Somewhat slack hand-rolled version: const int MinSectionLength = 1; +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + // Android has its own naming of zones. + // "Canada/East-Saskatchewan" has a 17-character second component. + const int MaxSectionLength = 17; +#else const int MaxSectionLength = 14; +#endif int sectionLength = 0; for (const char *it = ianaId.begin(), * const end = ianaId.end(); it != end; ++it, ++sectionLength) { const char ch = *it; diff --git a/tests/auto/corelib/time/qtimezone/BLACKLIST b/tests/auto/corelib/time/qtimezone/BLACKLIST index 840c3b1181..b820bab3d9 100644 --- a/tests/auto/corelib/time/qtimezone/BLACKLIST +++ b/tests/auto/corelib/time/qtimezone/BLACKLIST @@ -2,10 +2,6 @@ [dataStreamTest] android -# QTBUG-69128 -[isTimeZoneIdAvailable] -android - # QTBUG-69129 [specificTransition] android @@ -75,10 +71,14 @@ android android [transitionEachZone:Asia/Chita@1970] android +[transitionEachZone:Asia/Choibalsan@1970] +android [transitionEachZone:Asia/Dushanbe@1970] android [transitionEachZone:Asia/Ho_Chi_Minh@1970] android +[transitionEachZone:Asia/Hovd@1970] +android [transitionEachZone:Asia/Kathmandu@1970] android [transitionEachZone:Asia/Katmandu@1970] @@ -109,6 +109,10 @@ android android [transitionEachZone:Asia/Thimphu@1970] android +[transitionEachZone:Asia/Ulaanbaatar@1970] +android +[transitionEachZone:Asia/Ulan_Bator@1970] +android [transitionEachZone:Asia/Ust-Nera@1970] android [transitionEachZone:Atlantic/Cape_Verde@1970] diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp index 9f51ff8ba8..f425691d9c 100644 --- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp @@ -706,6 +706,7 @@ void tst_QTimeZone::isValidId_data() // a-z, A-Z, 0-9, '.', '-', '_' are valid chars // Can't start with '-' // Parts separated by '/', each part min 1 and max of 14 chars + // (Android has parts with lengths up to 17, so tolerates this as a special case.) #define TESTSET(name, section, valid) \ QTest::newRow(name " front") << QByteArray(section "/xyz/xyz") << valid; \ QTest::newRow(name " middle") << QByteArray("xyz/" section "/xyz") << valid; \ @@ -713,8 +714,13 @@ void tst_QTimeZone::isValidId_data() TESTSET("empty", "", false); TESTSET("minimal", "m", true); +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + TESTSET("maximal", "East-Saskatchewan", true); // Android actually uses this + TESTSET("too long", "North-Saskatchewan", false); // ... but thankfully not this. +#else TESTSET("maximal", "12345678901234", true); TESTSET("too long", "123456789012345", false); +#endif TESTSET("bad hyphen", "-hyphen", false); TESTSET("good hyphen", "hy-phen", true); @@ -759,8 +765,13 @@ void tst_QTimeZone::isValidId_data() QTest::newRow("a,z alone") << QByteArray("a,z") << false; QTest::newRow("/z alone") << QByteArray("/z") << false; QTest::newRow("-z alone") << QByteArray("-z") << false; +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + QTest::newRow("long alone") << QByteArray("12345678901234567") << true; + QTest::newRow("over-long alone") << QByteArray("123456789012345678") << false; +#else QTest::newRow("long alone") << QByteArray("12345678901234") << true; QTest::newRow("over-long alone") << QByteArray("123456789012345") << false; +#endif #else QSKIP("This test requires a Qt -developer-build."); -- cgit v1.2.3 From 80ac9e8b7ce8e3f79af0b00610a0a4b0ff17abe4 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 12 Nov 2019 17:59:51 +0100 Subject: Compile fix for MinGW 8.1.0 Workaround for libpng bug in GCC 8.1.0. Task-number: QTQAINFRA-3303 Change-Id: Id7668e795cb4ab16de3199fc3727d844aa31bfad Reviewed-by: Ville Voutilainen --- src/gui/image/image.pri | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index 3b2ced3f58..1f42f28d1e 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -79,6 +79,14 @@ qtConfig(png) { HEADERS += image/qpnghandler_p.h SOURCES += image/qpnghandler.cpp QMAKE_USE_PRIVATE += libpng + + win32:mingw { + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86048 + GCC_VERSION = "$${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.$${QMAKE_GCC_PATCH_VERSION}" + equals(GCC_VERSION, "8.1.0") { + QMAKE_CXXFLAGS += -fno-reorder-blocks-and-partition + } + } } # SIMD -- cgit v1.2.3 From c15a069830baf87f57c84e86326cf86ba9a39713 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 12 Jun 2019 20:49:06 +0200 Subject: QTreeView: make sure to not ask the old model during setModel Within QTreeView::setModel() the header might emit columnCountChanged which then tries to update the geometries based on the old model which is wrong. Fix it by setting geometryRecursionBlock to true so QTreeView::updateGeometries() will not ask the old model for it's data. Fixes: QTBUG-75982 Change-Id: Ia0dd36cd7c6c5347fbc285deac43da6941accbe7 Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qtreeview.cpp | 2 ++ tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 413cc2a9cd..034c1f4b4f 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -233,7 +233,9 @@ void QTreeView::setModel(QAbstractItemModel *model) d->viewItems.clear(); d->expandedIndexes.clear(); d->hiddenIndexes.clear(); + d->geometryRecursionBlock = true; // do not update geometries due to signals from the headers d->header->setModel(model); + d->geometryRecursionBlock = false; QAbstractItemView::setModel(model); // QAbstractItemView connects to a private slot diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 44195d3b25..58ca924fe2 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -2862,6 +2862,7 @@ public: }; Node *root; + bool crash = false; EvilModel(QObject *parent = nullptr): QAbstractItemModel(parent), root(new Node) {} @@ -2870,6 +2871,11 @@ public: delete root; } + void setCrash() + { + crash = true; + } + void change() { emit layoutAboutToBeChanged(); @@ -2938,6 +2944,10 @@ public: QVariant data(const QModelIndex &idx, int role) const override { + if (crash) { + QTest::qFail("Should not get here...", __FILE__, __LINE__); + return QVariant(); + } if (idx.isValid() && role == Qt::DisplayRole) { Node *parentNode = root; if (idx.isValid()) { @@ -2957,6 +2967,7 @@ void tst_QTreeView::evilModel_data() { QTest::addColumn("visible"); QTest::newRow("visible") << false; + QTest::newRow("visible") << true; } void tst_QTreeView::evilModel() @@ -3126,6 +3137,9 @@ void tst_QTreeView::evilModel() model.change(); view.setRootIndex(secondLevel); + + model.setCrash(); + view.setModel(nullptr); } void tst_QTreeView::indexRowSizeHint() -- cgit v1.2.3