diff options
52 files changed, 899 insertions, 563 deletions
diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 4dbe144913..13533555c5 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -13,7 +13,6 @@ defines += Q_QDOC \ QT_DEPRECATED \ QT_DEPRECATED_* \ Q_NO_USING_KEYWORD \ - __cplusplus \ Q_OS_.* \ Q_STDLIB_UNICODE_STRINGS \ Q_COMPILER_INITIALIZER_LISTS \ @@ -21,8 +20,7 @@ defines += Q_QDOC \ Q_COMPILER_UNIFORM_INIT \ Q_COMPILER_RVALUE_REFS -clangdefines += __cplusplus \ - Q_QDOC \ +clangdefines += Q_QDOC \ Q_CLANG_QDOC \ QT_COMPAT \ QT3_SUPPORT \ diff --git a/examples/widgets/doc/src/stylesheet.qdoc b/examples/widgets/doc/src/stylesheet.qdoc index a86b697059..26c5663022 100644 --- a/examples/widgets/doc/src/stylesheet.qdoc +++ b/examples/widgets/doc/src/stylesheet.qdoc @@ -48,7 +48,7 @@ \section1 MainWindow Class \c MainWindow inherits QWidget, and is the application's main window defined in - \c mainwindow.ui. The style of \c MainWindow can be modified with \l StyleSheetEditor. + \c mainwindow.ui. The style of \c MainWindow can be modified with \c StyleSheetEditor. \section1 StyleSheetEditor Class diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 74a716db4a..ce1b092a54 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -152,6 +152,44 @@ static inline bool simdDecodeAscii(ushort *&dst, const uchar *&nextAscii, const } return src == end; } + +static inline const uchar *simdFindNonAscii(const uchar *src, const uchar *end, const uchar *&nextAscii) +{ + // do sixteen characters at a time + for ( ; end - src >= 16; src += 16) { + __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src)); + + // check if everything is ASCII + // movemask extracts the high bit of every byte, so n is non-zero if something isn't ASCII + uint n = _mm_movemask_epi8(data); + if (!n) + continue; + + // find the next probable ASCII character + // we don't want to load 16 bytes again in this loop if we know there are non-ASCII + // characters still coming + nextAscii = src + qBitScanReverse(n) + 1; + + // return the non-ASCII character + return src + qCountTrailingZeroBits(n); + } + + // do four characters at a time + for ( ; end - src >= 4; src += 4) { + quint32 data = qFromUnaligned<quint32>(src); + data &= 0x80808080U; + if (!data) + continue; + + // We don't try to guess which of the three bytes is ASCII and which + // one isn't. The chance that at least two of them are non-ASCII is + // better than 75%. + nextAscii = src; + return src; + } + nextAscii = end; + return src; +} #elif defined(__ARM_NEON__) && defined(Q_PROCESSOR_ARM_64) // vaddv is only available on Aarch64 static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const ushort *&src, const ushort *end) { @@ -220,6 +258,34 @@ static inline bool simdDecodeAscii(ushort *&dst, const uchar *&nextAscii, const } return src == end; } + +static inline const uchar *simdFindNonAscii(const uchar *src, const uchar *end, const uchar *&nextAscii) +{ + // The SIMD code below is untested, so just force an early return until + // we've had the time to verify it works. + nextAscii = end; + return src; + + // do eight characters at a time + uint8x8_t msb_mask = vdup_n_u8(0x80); + uint8x8_t add_mask = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 }; + for ( ; end - src >= 8; src += 8) { + uint8x8_t c = vld1_u8(src); + uint8_t n = vaddv_u8(vand_u8(vcge_u8(c, msb_mask), add_mask)); + if (!n) + continue; + + // find the next probable ASCII character + // we don't want to load 16 bytes again in this loop if we know there are non-ASCII + // characters still coming + nextAscii = src + qBitScanReverse(n) + 1; + + // return the non-ASCII character + return src + qCountTrailingZeroBits(n); + } + nextAscii = end; + return src; +} #else static inline bool simdEncodeAscii(uchar *, const ushort *, const ushort *, const ushort *) { @@ -230,6 +296,12 @@ static inline bool simdDecodeAscii(ushort *, const uchar *, const uchar *, const { return false; } + +static inline const uchar *simdFindNonAscii(const uchar *src, const uchar *end, const uchar *&nextAscii) +{ + nextAscii = end; + return src; +} #endif QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len) @@ -518,6 +590,95 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte return result; } +struct QUtf8NoOutputTraits : public QUtf8BaseTraitsNoAscii +{ + struct NoOutput {}; + static void appendUtf16(const NoOutput &, ushort) {} + static void appendUcs4(const NoOutput &, uint) {} +}; + +QUtf8::ValidUtf8Result QUtf8::isValidUtf8(const char *chars, qsizetype len) +{ + const uchar *src = reinterpret_cast<const uchar *>(chars); + const uchar *end = src + len; + const uchar *nextAscii = src; + bool isValidAscii = true; + + while (src < end) { + if (src >= nextAscii) + src = simdFindNonAscii(src, end, nextAscii); + if (src == end) + break; + + do { + uchar b = *src++; + if ((b & 0x80) == 0) + continue; + + isValidAscii = false; + QUtf8NoOutputTraits::NoOutput output; + int res = QUtf8Functions::fromUtf8<QUtf8NoOutputTraits>(b, output, src, end); + if (res < 0) { + // decoding error + return { false, false }; + } + } while (src < nextAscii); + } + + return { true, isValidAscii }; +} + +int QUtf8::compareUtf8(const char *utf8, qsizetype u8len, const QChar *utf16, int u16len) +{ + uint uc1, uc2; + auto src1 = reinterpret_cast<const uchar *>(utf8); + auto end1 = src1 + u8len; + QStringIterator src2(utf16, utf16 + u16len); + + while (src1 < end1 && src2.hasNext()) { + uchar b = *src1++; + uint *output = &uc1; + int res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(b, output, src1, end1); + if (res < 0) { + // decoding error + uc1 = QChar::ReplacementCharacter; + } + + uc2 = src2.next(); + if (uc1 != uc2) + return int(uc1) - int(uc2); + } + + // the shorter string sorts first + return (end1 > src1) - int(src2.hasNext()); +} + +int QUtf8::compareUtf8(const char *utf8, qsizetype u8len, QLatin1String s) +{ + uint uc1; + auto src1 = reinterpret_cast<const uchar *>(utf8); + auto end1 = src1 + u8len; + auto src2 = reinterpret_cast<const uchar *>(s.latin1()); + auto end2 = src2 + s.size(); + + while (src1 < end1 && src2 < end2) { + uchar b = *src1++; + uint *output = &uc1; + int res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(b, output, src1, end1); + if (res < 0) { + // decoding error + uc1 = QChar::ReplacementCharacter; + } + + uint uc2 = *src2++; + if (uc1 != uc2) + return int(uc1) - int(uc2); + } + + // the shorter string sorts first + return (end1 > src1) - (end2 > src2); +} + QByteArray QUtf16::convertFromUnicode(const QChar *uc, int len, QTextCodec::ConverterState *state, DataEndianness e) { DataEndianness endian = e; diff --git a/src/corelib/codecs/qutfcodec_p.h b/src/corelib/codecs/qutfcodec_p.h index 36752cc909..659a229dae 100644 --- a/src/corelib/codecs/qutfcodec_p.h +++ b/src/corelib/codecs/qutfcodec_p.h @@ -290,6 +290,13 @@ struct QUtf8 static QString convertToUnicode(const char *, int, QTextCodec::ConverterState *); static QByteArray convertFromUnicode(const QChar *, int); static QByteArray convertFromUnicode(const QChar *, int, QTextCodec::ConverterState *); + struct ValidUtf8Result { + bool isValidUtf8; + bool isValidAscii; + }; + static ValidUtf8Result isValidUtf8(const char *, qsizetype); + static int compareUtf8(const char *, qsizetype, const QChar *, int); + static int compareUtf8(const char *, qsizetype, QLatin1String s); }; struct QUtf16 diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index c6197660e7..1fe1c8c0d1 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3610,7 +3610,7 @@ bool qunsetenv(const char *varName) */ /*! - \fn template <typename T> qAsConst(T &t) + \fn template <typename T> typename std::add_const<T>::type &qAsConst(T &t) \relates <QtGlobal> \since 5.7 @@ -3662,7 +3662,7 @@ bool qunsetenv(const char *varName) */ /*! - \fn template <typename T> qAsConst(const T &&t) + \fn template <typename T> void qAsConst(const T &&t) \relates <QtGlobal> \since 5.7 \overload diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index a3cab2b627..c727d5738b 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1664,7 +1664,7 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con handledStderr |= android_default_message_handler(type, context, message); #endif - if (handledStderr || !qt_logging_to_console()) + if (handledStderr) return; QString formattedMessage = qFormatLogMessage(type, context, message); diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index fb40c71f7a..31b1823690 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1406,6 +1406,9 @@ public: ImhMultiLine = 0x400, + ImhNoEditMenu = 0x800, + ImhNoTextHandles = 0x1000, + ImhDigitsOnly = 0x10000, ImhFormattedNumbersOnly = 0x20000, ImhUppercaseOnly = 0x40000, diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index dd0b18dfa0..11c431d015 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -993,12 +993,7 @@ \value WA_LayoutUsesWidgetRect Ignore the layout item rect from the style when laying out this widget with QLayout. - \value WA_MacNoClickThrough When a widget that has this attribute set - is clicked, and its window is inactive, the click will make the window - active but won't be seen by the widget. Typical use of this attribute - is on widgets with "destructive" actions, such as a "Delete" button. - WA_MacNoClickThrough also applies to all child widgets of the widget - that has it set. + \value WA_MacNoClickThrough This value is obsolete and has no effect. \value WA_MacOpaqueSizeGrip Indicates that the native Carbon size grip should be opaque instead of transparent (the default). This attribute @@ -1027,9 +1022,7 @@ alternative sizes for widgets to avoid clipping. This attribute is only applicable to \macos. - \value WA_MacBrushedMetal Indicates the widget should be drawn in - the brushed metal style as supported by the windowing system. This - attribute is only applicable to \macos. + \value WA_MacBrushedMetal This value is obsolete and has no effect. \omitvalue WA_MacMetalStyle @@ -1284,9 +1277,7 @@ has no effect on non-X11 platforms. \b Note: Qt automatically sets this attribute on the feedback widget used during a drag. - \value WA_MacFrameworkScaled Enables resolution independence aware mode - on Mac when using Carbon. This attribute has no effect on Cocoa. - The attribute is off by default and can be enabled on a per-window basis. + \value WA_MacFrameworkScaled This value is obsolete and has no effect. \value WA_AcceptTouchEvents Allows touch events (see QTouchEvent) to be sent to the widget. Must be set on all widgets that can @@ -2160,7 +2151,7 @@ with a somewhat lighter frame. It can also be combined with Qt::FramelessWindowHint. On \macos, tool windows correspond to the - \l{http://developer.apple.com/documentation/Carbon/Conceptual/HandlingWindowsControls/hitb-wind_cont_concept/chapter_2_section_2.html}{Floating} + \l{https://developer.apple.com/documentation/appkit/nspanel}{NSPanel} class of windows. This means that the window lives on a level above normal windows making it impossible to put a normal window on top of it. By default, tool windows will disappear @@ -2595,6 +2586,9 @@ \value ImhMultiLine Multiple lines can be entered into the text field. + \value ImhNoEditMenu Do not use built-in edit menu. This flag was introduced in Qt 5.11. + \value ImhNoTextHandles Do not use built-in text cursor and selection handles. This flag was introduced in Qt 5.11. + Flags that restrict input (exclusive flags): \value ImhDigitsOnly Only digits are allowed. diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 24f36b3b01..7ccacd883f 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -440,10 +440,10 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) *str = v_cast<QDate>(d)->toString(Qt::ISODate); break; case QVariant::Time: - *str = v_cast<QTime>(d)->toString(Qt::ISODate); + *str = v_cast<QTime>(d)->toString(Qt::ISODateWithMs); break; case QVariant::DateTime: - *str = v_cast<QDateTime>(d)->toString(Qt::ISODate); + *str = v_cast<QDateTime>(d)->toString(Qt::ISODateWithMs); break; #endif case QVariant::Bool: diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 5dfbf23c33..b113ca13ce 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -83,21 +83,27 @@ bool _q_fromHex(const char *&src, Integral &value) return true; } -static char *_q_uuidToHex(const QUuid &uuid, char *dst) +static char *_q_uuidToHex(const QUuid &uuid, char *dst, QUuid::StringFormat mode = QUuid::WithBraces) { - *dst++ = '{'; + if ((mode & QUuid::WithoutBraces) == 0) + *dst++ = '{'; _q_toHex(dst, uuid.data1); - *dst++ = '-'; + if ((mode & QUuid::Id128) != QUuid::Id128) + *dst++ = '-'; _q_toHex(dst, uuid.data2); - *dst++ = '-'; + if ((mode & QUuid::Id128) != QUuid::Id128) + *dst++ = '-'; _q_toHex(dst, uuid.data3); - *dst++ = '-'; + if ((mode & QUuid::Id128) != QUuid::Id128) + *dst++ = '-'; for (int i = 0; i < 2; i++) _q_toHex(dst, uuid.data4[i]); - *dst++ = '-'; + if ((mode & QUuid::Id128) != QUuid::Id128) + *dst++ = '-'; for (int i = 2; i < 8; i++) _q_toHex(dst, uuid.data4[i]); - *dst++ = '}'; + if ((mode & QUuid::WithoutBraces) == 0) + *dst++ = '}'; return dst; } @@ -305,6 +311,22 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto */ /*! + \enum QUuid::StringFormat + \since 5.11 + + This enum is used by toString(StringFormat) to control the formatting of the + string representation. The possible values are: + + \value WithBraces The default, toString() will return five hex fields, separated by + dashes and surrounded by braces. Example: + {00000000-0000-0000-0000-000000000000}. + \value WithoutBraces Only the five dash-separated fields, without the braces. Example: + 00000000-0000-0000-0000-000000000000. + \value Id128 Only the hex digits, without braces or dashes. Note that QUuid + cannot parse this back again as input. +*/ + +/*! \fn QUuid::QUuid(const GUID &guid) Casts a Windows \a guid to a Qt QUuid. @@ -590,6 +612,47 @@ QString QUuid::toString() const } /*! + \since 5.11 + + Returns the string representation of this QUuid, with the formattiong + controlled by the \a mode parameter. From left to right, the five hex + fields are obtained from the four public data members in QUuid as follows: + + \table + \header + \li Field # + \li Source + + \row + \li 1 + \li data1 + + \row + \li 2 + \li data2 + + \row + \li 3 + \li data3 + + \row + \li 4 + \li data4[0] .. data4[1] + + \row + \li 5 + \li data4[2] .. data4[7] + + \endtable +*/ +QString QUuid::toString(QUuid::StringFormat mode) const +{ + char latin1[MaxStringUuidLength]; + const auto end = _q_uuidToHex(*this, latin1, mode); + return QString::fromLatin1(latin1, end - latin1); +} + +/*! Returns the binary representation of this QUuid. The byte array is formatted as five hex fields separated by '-' and enclosed in curly braces, i.e., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where @@ -635,6 +698,48 @@ QByteArray QUuid::toByteArray() const } /*! + \since 5.11 + + Returns the string representation of this QUuid, with the formattiong + controlled by the \a mode parameter. From left to right, the five hex + fields are obtained from the four public data members in QUuid as follows: + + \table + \header + \li Field # + \li Source + + \row + \li 1 + \li data1 + + \row + \li 2 + \li data2 + + \row + \li 3 + \li data3 + + \row + \li 4 + \li data4[0] .. data4[1] + + \row + \li 5 + \li data4[2] .. data4[7] + + \endtable +*/ +QByteArray QUuid::toByteArray(QUuid::StringFormat mode) const +{ + QByteArray result(MaxStringUuidLength, Qt::Uninitialized); + const auto end = _q_uuidToHex(*this, const_cast<char*>(result.constData()), mode); + result.resize(end - result.constData()); + return result; +} + +/*! Returns the binary representation of this QUuid. The byte array is in big endian format, and formatted according to RFC 4122, section 4.1.2 - "Layout and byte order". diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h index 014b69831e..08a1843640 100644 --- a/src/corelib/plugin/quuid.h +++ b/src/corelib/plugin/quuid.h @@ -85,7 +85,14 @@ public: Sha1 = 5 // 0 1 0 1 }; + enum StringFormat { + WithBraces = 0, + WithoutBraces = 1, + Id128 = 3 + }; + #if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_CLANG_QDOC) + Q_DECL_CONSTEXPR QUuid() Q_DECL_NOTHROW : data1(0), data2(0), data3(0), data4{0,0,0,0,0,0,0,0} {} Q_DECL_CONSTEXPR QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, @@ -121,8 +128,10 @@ public: static QUuid fromString(QLatin1String string) Q_DECL_NOTHROW; QUuid(const char *); QString toString() const; + QString toString(StringFormat mode) const; // ### Qt6: merge with previous QUuid(const QByteArray &); QByteArray toByteArray() const; + QByteArray toByteArray(StringFormat mode) const; // ### Qt6: merge with previous QByteArray toRfc4122() const; static QUuid fromRfc4122(const QByteArray &); bool isNull() const Q_DECL_NOTHROW; diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index dd86a80e9d..336f2afaca 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -516,7 +516,9 @@ Typedef for \c{std::reverse_iterator<T*>}. Provided for STL compatibility. */ -/*! \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::prepend(const T &value) +/*! + \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::prepend(const T &value) + \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::prepend(T &&value) \since 4.8 Inserts \a value at the beginning of the array. @@ -533,13 +535,6 @@ \sa append(), insert() */ -/*! - \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::prepend(T &&value) - \since 5.11 - - \overload -*/ - /*! \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::replace(int i, const T &value) \since 4.8 @@ -703,7 +698,9 @@ before the call. */ -/*! \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::insert(int i, const T &value) +/*! + \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::insert(int i, const T &value) + \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::insert(int i, T &&value) \since 4.8 Inserts \a value at index position \a i in the array. If \a i is @@ -728,15 +725,8 @@ vector. */ - -/*! \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::insert(int i, T &&value) - - \overload - \since 5.11 - -*/ - /*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, const T &value) + \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, T &&value) \overload \since 4.8 @@ -745,12 +735,6 @@ \a before. Returns an iterator pointing at the inserted item. */ -/*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, T &&value) - - \overload - \since 5.11 -*/ - /*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, int count, const T &value) \since 4.8 diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 5ebf7f7435..24a19e68d4 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -72,7 +72,7 @@ public: inline QVector(const QVector<T> &v); inline ~QVector() { if (!d->ref.deref()) freeData(d); } QVector<T> &operator=(const QVector<T> &v); -#ifdef Q_COMPILER_RVALUE_REFS +#if defined(Q_COMPILER_RVALUE_REFS) || defined(Q_CLANG_QDOC) QVector(QVector<T> &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); } QVector<T> &operator=(QVector<T> &&other) Q_DECL_NOTHROW { QVector moved(std::move(other)); swap(moved); return *this; } @@ -133,7 +133,7 @@ public: T &operator[](int i); const T &operator[](int i) const; void append(const T &t); -#ifdef Q_COMPILER_RVALUE_REFS +#if defined(Q_COMPILER_RVALUE_REFS) || defined(Q_CLANG_QDOC) void append(T &&t); #endif inline void append(const QVector<T> &l) { *this += l; } @@ -201,7 +201,7 @@ public: typedef typename Data::const_iterator const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; -#if !defined(QT_STRICT_ITERATORS) || defined(Q_QDOC) +#if !defined(QT_STRICT_ITERATORS) || defined(Q_CLANG_QDOC) inline iterator begin() { detach(); return d->begin(); } inline const_iterator begin() const Q_DECL_NOTHROW { return d->constBegin(); } inline const_iterator cbegin() const Q_DECL_NOTHROW { return d->constBegin(); } @@ -258,7 +258,7 @@ public: typedef const_iterator ConstIterator; typedef int size_type; inline void push_back(const T &t) { append(t); } -#ifdef Q_COMPILER_RVALUE_REFS +#if defined(Q_COMPILER_RVALUE_REFS) || defined(Q_CLANG_QDOC) void push_back(T &&t) { append(std::move(t)); } void push_front(T &&t) { prepend(std::move(t)); } #endif diff --git a/src/corelib/tools/qvector.qdoc b/src/corelib/tools/qvector.qdoc index e344a9023d..cc250b72a5 100644 --- a/src/corelib/tools/qvector.qdoc +++ b/src/corelib/tools/qvector.qdoc @@ -587,7 +587,9 @@ */ -/*! \fn template <typename T> void QVector<T>::prepend(const T &value) +/*! + \fn template <typename T> void QVector<T>::prepend(const T &value) + \fn template <typename T> void QVector<T>::prepend(T &&value) Inserts \a value at the beginning of the vector. @@ -605,17 +607,8 @@ \sa append(), insert() */ -/*! - \fn template <typename T> void QVector<T>::prepend(T &&value) - \since 5.11 - - \overload - - Inserts \a value at the beginning of the vector using move semantics. -*/ - - /*! \fn template <typename T> void QVector<T>::insert(int i, const T &value) + \fn template <typename T> void QVector<T>::insert(int i, T &&value) Inserts \a value at index position \a i in the vector. If \a i is 0, the value is prepended to the vector. If \a i is size(), the @@ -633,14 +626,6 @@ \sa append(), prepend(), remove() */ -/*! \fn template <typename T> void QVector<T>::insert(int i, T &&value) - \since 5.11 - - \overload - - Inserts \a value at index position \a i in the vector using move semantics. -*/ - /*! \fn template <typename T> void QVector<T>::insert(int i, int count, const T &value) \overload @@ -652,7 +637,9 @@ \snippet code/src_corelib_tools_qvector.cpp 10 */ -/*! \fn template <typename T> QVector<T>::iterator QVector<T>::insert(iterator before, const T &value) +/*! + \fn template <typename T> QVector<T>::iterator QVector<T>::insert(iterator before, const T &value) + \fn template <typename T> QVector<T>::iterator QVector<T>::insert(iterator before, T &&value) \overload @@ -1102,17 +1089,14 @@ \overload */ -/*! \fn template <typename T> void QVector<T>::push_front(const T &value) +/*! + \fn template <typename T> void QVector<T>::push_front(const T &value) + \fn template <typename T> void QVector<T>::push_front(T &&value) This function is provided for STL compatibility. It is equivalent to prepend(\a value). */ -/*! \fn template <typename T> void QVector<T>::push_front(T &&value) - \since 5.11 - \overload -*/ - /*! \fn template <typename T> void QVector<T>::pop_front() This function is provided for STL compatibility. It is equivalent diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 70b4869442..055347500b 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2283,6 +2283,8 @@ void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfa void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *wse) { if (QWindow *window = wse->window.data()) { + if (window->screen() == wse->screen.data()) + return; if (window->isTopLevel()) { if (QScreen *screen = wse->screen.data()) window->d_func()->setTopLevelScreen(screen, false /* recreate */); diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 71ecc46cb6..9a9677b476 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -42,7 +42,7 @@ #include <qpa/qplatformtheme.h> #include "private/qguiapplication_p.h" -#ifndef QT_NO_SHORTCUT +#if !defined(QT_NO_SHORTCUT) || defined(Q_CLANG_QDOC) #include "qdebug.h" #include <QtCore/qhashfunctions.h> @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE -#if defined(Q_OS_MACX) +#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC) static bool qt_sequence_no_mnemonics = true; struct MacSpecialKey { int key; diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h index 82b88e5d99..65f3a93d9c 100644 --- a/src/gui/kernel/qkeysequence.h +++ b/src/gui/kernel/qkeysequence.h @@ -47,19 +47,19 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_SHORTCUT +#if !defined(QT_NO_SHORTCUT) || defined(Q_CLANG_QDOC) class QKeySequence; /***************************************************************************** QKeySequence stream functions *****************************************************************************/ -#ifndef QT_NO_DATASTREAM +#if !defined(QT_NO_DATASTREAM) || defined(Q_CLANG_QDOC) Q_GUI_EXPORT QDataStream &operator<<(QDataStream &in, const QKeySequence &ks); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &out, QKeySequence &ks); #endif -#ifdef Q_CLANG_QDOC +#if defined(Q_CLANG_QDOC) void qt_set_sequence_auto_mnemonic(bool b); #endif @@ -225,7 +225,7 @@ public: Q_DECLARE_SHARED(QKeySequence) -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) || defined(Q_CLANG_QDOC) Q_GUI_EXPORT QDebug operator<<(QDebug, const QKeySequence &); #endif diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 4bf96e277f..a66420c364 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -475,6 +475,25 @@ bool QPlatformWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) } /*! + Reimplement this method to start a system move operation if + the system supports it and return true to indicate success. + + The \a pos is a position of MouseButtonPress event or TouchBegin + event from a sequence of mouse events that triggered the movement. + It must be specified in window coordinates. + + The default implementation is empty and does nothing with \a pos. + + \since 5.11 +*/ + +bool QPlatformWindow::startSystemMove(const QPoint &pos) +{ + Q_UNUSED(pos) + return false; +} + +/*! Reimplement this method to set whether frame strut events should be sent to \a enabled. diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 61f1cb624c..84dff681d5 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -129,6 +129,7 @@ public: virtual void windowEvent(QEvent *event); virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner); + virtual bool startSystemMove(const QPoint &pos); virtual void setFrameStrutEventsEnabled(bool enabled); virtual bool frameStrutEventsEnabled() const; diff --git a/src/platformheaders/eglfsfunctions/qeglfsfunctions.h b/src/platformheaders/eglfsfunctions/qeglfsfunctions.h index 67522ec9be..7165c3cff4 100644 --- a/src/platformheaders/eglfsfunctions/qeglfsfunctions.h +++ b/src/platformheaders/eglfsfunctions/qeglfsfunctions.h @@ -98,6 +98,15 @@ public: return func && func(screen, id, position); } + typedef bool (*Vsp2SetLayerAlphaType)(const QScreen *screen, int id, qreal alpha); + static QByteArray vsp2SetLayerAlphaTypeIdentifier() { return QByteArrayLiteral("EglFSVsp2SetLayerAlpha"); } + + static bool vsp2SetLayerAlpha(const QScreen *screen, int id, qreal alpha) + { + auto func = reinterpret_cast<Vsp2SetLayerAlphaType>(QGuiApplication::platformFunction(vsp2SetLayerAlphaTypeIdentifier())); + return func && func(screen, id, alpha); + } + typedef void (*Vsp2AddBlendListenerType)(const QScreen *screen, void(*callback)()); static QByteArray vsp2AddBlendListenerTypeIdentifier() { return QByteArrayLiteral("EglFSVsp2AddBlendListener"); } diff --git a/src/platformsupport/edid/qedidparser_p.h b/src/platformsupport/edid/qedidparser_p.h index c5888dc5d7..c436155258 100644 --- a/src/platformsupport/edid/qedidparser_p.h +++ b/src/platformsupport/edid/qedidparser_p.h @@ -47,10 +47,12 @@ // W A R N I N G // ------------- // -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to // version without notice, or even be removed. // +// We mean it. +// QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/edid/qedidvendortable_p.h b/src/platformsupport/edid/qedidvendortable_p.h index 948a9cecfc..6ec399df05 100644 --- a/src/platformsupport/edid/qedidvendortable_p.h +++ b/src/platformsupport/edid/qedidvendortable_p.h @@ -51,10 +51,12 @@ // W A R N I N G // ------------- // -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to // version without notice, or even be removed. // +// We mean it. +// QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 7397312820..2edee51989 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -686,9 +686,11 @@ static CTFontUIFontType fontTypeFromTheme(QPlatformTheme::Font f) return kCTFontUIFontWindowTitle; case QPlatformTheme::MdiSubWindowTitleFont: - case QPlatformTheme::DockWidgetTitleFont: return kCTFontUIFontSystem; + case QPlatformTheme::DockWidgetTitleFont: + return kCTFontUIFontSmallSystem; + case QPlatformTheme::PushButtonFont: return kCTFontUIFontPushButton; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp index f85d6183f6..0d9b6b6290 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp @@ -133,6 +133,8 @@ QFunctionPointer QEglFSKmsVsp2Integration::platformFunction(const QByteArray &fu return QFunctionPointer(setLayerBufferStatic); if (function == QEglFSFunctions::vsp2SetLayerPositionTypeIdentifier()) return QFunctionPointer(setLayerPositionStatic); + if (function == QEglFSFunctions::vsp2SetLayerAlphaTypeIdentifier()) + return QFunctionPointer(setLayerAlphaStatic); if (function == QEglFSFunctions::vsp2AddBlendListenerTypeIdentifier()) return QFunctionPointer(addBlendListenerStatic); @@ -184,6 +186,12 @@ void QEglFSKmsVsp2Integration::setLayerPositionStatic(const QScreen *screen, int vsp2Screen->setLayerPosition(id, position); } +void QEglFSKmsVsp2Integration::setLayerAlphaStatic(const QScreen *screen, int id, qreal alpha) +{ + auto vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen->handle()); + vsp2Screen->setLayerAlpha(id, alpha); +} + void QEglFSKmsVsp2Integration::addBlendListenerStatic(const QScreen *screen, void(*callback)()) { auto vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen->handle()); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.h index c09ee205c8..b1a8a2edf3 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.h @@ -72,6 +72,7 @@ private: static bool removeLayerStatic(const QScreen *screen, int id); static void setLayerBufferStatic(const QScreen *screen, int id, int dmabufFd); static void setLayerPositionStatic(const QScreen *screen, int id, const QPoint &position); + static void setLayerAlphaStatic(const QScreen *screen, int id, qreal alpha); static void addBlendListenerStatic(const QScreen *screen, void(*callback)()); }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp index 42af93287d..88b401c920 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp @@ -186,6 +186,12 @@ void QEglFSKmsVsp2Screen::setLayerPosition(int id, const QPoint &position) m_blendDevice->setInputPosition(layerIndex, position); } +void QEglFSKmsVsp2Screen::setLayerAlpha(int id, qreal alpha) +{ + int layerIndex = id; + m_blendDevice->setInputAlpha(layerIndex, alpha); +} + bool QEglFSKmsVsp2Screen::removeLayer(int id) { int layerIndex = id; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h index 19f65e7e7d..fa03e36785 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h @@ -65,6 +65,7 @@ public: int addLayer(int dmabufFd, const QSize &size, const QPoint &position, uint drmPixelFormat, uint bytesPerLine); void setLayerBuffer(int id, int dmabufFd); void setLayerPosition(int id, const QPoint &position); + void setLayerAlpha(int id, qreal alpha); bool removeLayer(int id); void addBlendListener(void (*callback)()); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.cpp index 21de052b87..25b0c39050 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.cpp @@ -533,6 +533,14 @@ bool QLinuxMediaDevice::OutputSubDevice::streamOff() return QLinuxMediaDevice::streamOff(m_subdevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); } +int QLinuxMediaDevice::openVideoDevice(media_pad *pad) +{ + const char *deviceName = media_entity_get_devname(pad->entity); + int fd = open(deviceName, O_RDWR); + qCDebug(qLcEglfsKmsDebug) << "Opened video device:" << deviceName << "with fd" << fd; + return fd; +} + bool QLinuxMediaDevice::setSubdevFormat(struct media_pad *pad, const QSize &size, uint32_t mbusFormat) { Q_ASSERT(size.isValid()); @@ -556,6 +564,18 @@ bool QLinuxMediaDevice::setSubdevFormat(struct media_pad *pad, const QSize &size return true; } +bool QLinuxMediaDevice::setSubdevAlpha(int subdevFd, qreal alpha) +{ + struct v4l2_control control; + control.id = V4L2_CID_ALPHA_COMPONENT; + control.value = static_cast<__s32>(alpha * 0xff); + if (ioctl(subdevFd, VIDIOC_S_CTRL, &control) == -1) { + qErrnoWarning("Setting alpha (%d) failed", control.value); + return false; + } + return true; +} + bool QLinuxMediaDevice::setSubdevSelection(struct media_pad *pad, const QRect &geometry, uint target) { Q_ASSERT(geometry.isValid()); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.h index 848099eb46..26f863214b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.h @@ -95,7 +95,10 @@ public: int m_subdevFd = -1; }; + static int openVideoDevice(media_pad *pad); + static bool setSubdevFormat(struct media_pad *pad, const QSize &size, uint32_t mbusFormat = MEDIA_BUS_FMT_ARGB8888_1X32); + static bool setSubdevAlpha(int subdevFd, qreal alpha); static bool setSubdevSelection(struct media_pad *pad, const QRect &geometry, uint target); static bool setSubdevCrop(struct media_pad *pad, const QRect &geometry); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp index c9b9bb5b7f..58ffd31afd 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp @@ -99,6 +99,7 @@ QVsp2BlendingDevice::QVsp2BlendingDevice(const QSize &screenSize) input.linkToBru = md.parseLink(QString("'%1 rpf.%2':1 -> '%1 bru':%2").arg(deviceName).arg(i)); input.inputFormatPad = md.parsePad(QString("'%1 rpf.%2':0").arg(deviceName).arg(i)); input.outputFormatPad = md.parsePad(QString("'%1 rpf.%2':1").arg(deviceName).arg(i)); + input.outputFormatFd = QLinuxMediaDevice::openVideoDevice(input.outputFormatPad); input.bruInputFormatPad = md.parsePad(QString("'%1 bru':%2").arg(deviceName).arg(i)); input.rpfInput = new QLinuxMediaDevice::OutputSubDevice(&md, QString("%1 rpf.%2 input").arg(deviceName).arg(i)); m_inputs.append(input); @@ -202,6 +203,17 @@ bool QVsp2BlendingDevice::setInputPosition(int index, const QPoint &position) return QLinuxMediaDevice::setSubdevCompose(input.bruInputFormatPad, input.geometry); } +bool QVsp2BlendingDevice::setInputAlpha(int index, qreal alpha) +{ + Input &input = m_inputs[index]; + if (input.alpha == alpha) + return true; + + m_dirty = true; + input.alpha = alpha; + return QLinuxMediaDevice::setSubdevAlpha(input.outputFormatFd, alpha); +} + bool QVsp2BlendingDevice::blend(int outputDmabufFd) { if (!m_dirty) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h index ff2d581d72..be48954f47 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h @@ -59,6 +59,7 @@ public: bool disableInput(int i); bool setInputBuffer(int index, int dmabufFd); bool setInputPosition(int index, const QPoint &position); + bool setInputAlpha(int index, qreal alpha); bool blend(int outputDmabufFd); int numInputs() const; bool isDirty() const { return m_dirty; } @@ -71,6 +72,7 @@ private: struct Input { bool enabled = false; QRect geometry; + qreal alpha = 1; struct { int fd = -1; uint bytesUsed = 0; @@ -79,6 +81,7 @@ private: struct media_link *linkToBru = nullptr; //rpf.x:1 -> bru:x struct media_pad *inputFormatPad = nullptr; // rpf.x:0 struct media_pad *outputFormatPad = nullptr; // rpf.x:1 + int outputFormatFd = -1; // rpf.x:1 (again, because v4l2_subdev_* doesn't have a way to set alpha) struct media_pad *bruInputFormatPad = nullptr; // bru:x QLinuxMediaDevice::OutputSubDevice *rpfInput = nullptr; // rpf.x input }; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 92825acb6d..07df963ec5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -523,7 +523,7 @@ public: void xi2UpdateScrollingDevices(); #endif #ifdef XCB_USE_XINPUT22 - bool startSystemResizeForTouchBegin(xcb_window_t window, const QPoint &point, Qt::Corner corner); + bool startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner); bool isTouchScreen(int id); #endif #endif @@ -676,12 +676,12 @@ private: #if QT_CONFIG(xinput2) QHash<int, TouchDeviceData> m_touchDevices; #ifdef XCB_USE_XINPUT22 - struct StartSystemResizeInfo { + struct StartSystemMoveResizeInfo { xcb_window_t window = XCB_NONE; uint16_t deviceid; uint32_t pointid; - Qt::Corner corner; - } m_startSystemResizeInfo; + int corner; + } m_startSystemMoveResizeInfo; #endif #endif WindowMapper m_mapper; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index ba6481082a..39d2857212 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -784,15 +784,15 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo } if (dev->qtTouchDevice->type() == QTouchDevice::TouchScreen && - xiDeviceEvent->event == m_startSystemResizeInfo.window && - xiDeviceEvent->sourceid == m_startSystemResizeInfo.deviceid && - xiDeviceEvent->detail == m_startSystemResizeInfo.pointid) { - QXcbWindow *window = platformWindowFromId(m_startSystemResizeInfo.window); + xiDeviceEvent->event == m_startSystemMoveResizeInfo.window && + xiDeviceEvent->sourceid == m_startSystemMoveResizeInfo.deviceid && + xiDeviceEvent->detail == m_startSystemMoveResizeInfo.pointid) { + QXcbWindow *window = platformWindowFromId(m_startSystemMoveResizeInfo.window); if (window) { XIAllowTouchEvents(static_cast<Display *>(m_xlib_display), xiDeviceEvent->deviceid, xiDeviceEvent->detail, xiDeviceEvent->event, XIRejectTouch); - window->doStartSystemResize(QPoint(x, y), m_startSystemResizeInfo.corner); - m_startSystemResizeInfo.window = XCB_NONE; + window->doStartSystemMoveResize(QPoint(x, y), m_startSystemMoveResizeInfo.corner); + m_startSystemMoveResizeInfo.window = XCB_NONE; } } break; @@ -825,7 +825,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo touchPoint.state = Qt::TouchPointStationary; } -bool QXcbConnection::startSystemResizeForTouchBegin(xcb_window_t window, const QPoint &point, Qt::Corner corner) +bool QXcbConnection::startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner) { QHash<int, TouchDeviceData>::const_iterator devIt = m_touchDevices.constBegin(); for (; devIt != m_touchDevices.constEnd(); ++devIt) { @@ -834,10 +834,10 @@ bool QXcbConnection::startSystemResizeForTouchBegin(xcb_window_t window, const Q QHash<int, QPointF>::const_iterator pointIt = deviceData.pointPressedPosition.constBegin(); for (; pointIt != deviceData.pointPressedPosition.constEnd(); ++pointIt) { if (pointIt.value().toPoint() == point) { - m_startSystemResizeInfo.window = window; - m_startSystemResizeInfo.deviceid = devIt.key(); - m_startSystemResizeInfo.pointid = pointIt.key(); - m_startSystemResizeInfo.corner = corner; + m_startSystemMoveResizeInfo.window = window; + m_startSystemMoveResizeInfo.deviceid = devIt.key(); + m_startSystemMoveResizeInfo.pointid = pointIt.key(); + m_startSystemMoveResizeInfo.corner = corner; return true; } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 89ace781ae..5b05a230e4 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2640,18 +2640,28 @@ void QXcbWindow::windowEvent(QEvent *event) bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) { + return startSystemMoveResize(pos, corner); +} + +bool QXcbWindow::startSystemMove(const QPoint &pos) +{ + return startSystemMoveResize(pos, 4); +} + +bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) +{ const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); if (!connection()->wmSupport()->isSupportedByWM(moveResize)) return false; const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen()); #ifdef XCB_USE_XINPUT22 - if (connection()->startSystemResizeForTouchBegin(m_window, globalPos, corner)) + if (connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner)) return true; #endif - return doStartSystemResize(globalPos, corner); + return doStartSystemMoveResize(globalPos, corner); } -bool QXcbWindow::doStartSystemResize(const QPoint &globalPos, Qt::Corner corner) +bool QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner) { const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); xcb_client_message_event_t xev; @@ -2662,12 +2672,16 @@ bool QXcbWindow::doStartSystemResize(const QPoint &globalPos, Qt::Corner corner) xev.format = 32; xev.data.data32[0] = globalPos.x(); xev.data.data32[1] = globalPos.y(); - const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner; - const bool left = corner == Qt::BottomLeftCorner || corner == Qt::TopLeftCorner; - if (bottom) - xev.data.data32[2] = left ? 6 : 4; // bottomleft/bottomright - else - xev.data.data32[2] = left ? 0 : 2; // topleft/topright + if (corner == 4) { + xev.data.data32[2] = 8; // move + } else { + const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner; + const bool left = corner == Qt::BottomLeftCorner || corner == Qt::TopLeftCorner; + if (bottom) + xev.data.data32[2] = left ? 6 : 4; // bottomleft/bottomright + else + xev.data.data32[2] = left ? 0 : 2; // topleft/topright + } xev.data.data32[3] = XCB_BUTTON_INDEX_1; xev.data.data32[4] = 0; xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 65221394ea..957c4e9cbd 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -110,6 +110,7 @@ public: void windowEvent(QEvent *event) override; bool startSystemResize(const QPoint &pos, Qt::Corner corner) override; + bool startSystemMove(const QPoint &pos) override; void setOpacity(qreal level) override; void setMask(const QRegion ®ion) override; @@ -177,7 +178,8 @@ public: QXcbScreen *xcbScreen() const; - bool doStartSystemResize(const QPoint &globalPos, Qt::Corner corner); + bool startSystemMoveResize(const QPoint &pos, int corner); + bool doStartSystemMoveResize(const QPoint &globalPos, int corner); virtual void create(); virtual void destroy(); diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index a5d94ec9b9..10fe3f6f0e 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -301,6 +301,10 @@ static const QColor mainWindowGradientEnd(200, 200, 200); static const int DisclosureOffset = 4; +static const qreal titleBarIconTitleSpacing = 5; +static const qreal titleBarTitleRightMargin = 12; +static const qreal titleBarButtonSpacing = 8; + // Tab bar colors // active: window is active // selected: tab is selected @@ -664,7 +668,6 @@ const int qt_mac_hitheme_version = 0; //the HITheme version we speak const int macItemFrame = 2; // menu item frame width const int macItemHMargin = 3; // menu item hor text margin const int macRightBorder = 12; // right border on mac -const ThemeWindowType QtWinType = kThemeDocumentWindow; // Window type we use for QTitleBar. /***************************************************************************** QMacCGStyle utility functions @@ -1251,6 +1254,58 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRect &targetRect, int h p->restore(); } +QPainterPath QMacStylePrivate::windowPanelPath(const QRectF &r) const +{ + static const qreal CornerPointOffset = 5.5; + static const qreal CornerControlOffset = 2.1; + + QPainterPath path; + // Top-left corner + path.moveTo(r.left(), r.top() + CornerPointOffset); + path.cubicTo(r.left(), r.top() + CornerControlOffset, + r.left() + CornerControlOffset, r.top(), + r.left() + CornerPointOffset, r.top()); + // Top-right corner + path.lineTo(r.right() - CornerPointOffset, r.top()); + path.cubicTo(r.right() - CornerControlOffset, r.top(), + r.right(), r.top() + CornerControlOffset, + r.right(), r.top() + CornerPointOffset); + // Bottom-right corner + path.lineTo(r.right(), r.bottom() - CornerPointOffset); + path.cubicTo(r.right(), r.bottom() - CornerControlOffset, + r.right() - CornerControlOffset, r.bottom(), + r.right() - CornerPointOffset, r.bottom()); + // Bottom-right corner + path.lineTo(r.left() + CornerPointOffset, r.bottom()); + path.cubicTo(r.left() + CornerControlOffset, r.bottom(), + r.left(), r.bottom() - CornerControlOffset, + r.left(), r.bottom() - CornerPointOffset); + path.lineTo(r.left(), r.top() + CornerPointOffset); + + return path; +} + +QMacStylePrivate::CocoaControlType QMacStylePrivate::windowButtonCocoaControl(QStyle::SubControl sc) const +{ + struct WindowButtons { + QStyle::SubControl sc; + QMacStylePrivate::CocoaControlType ct; + }; + + static const WindowButtons buttons[] = { + { QStyle::SC_TitleBarCloseButton, QMacStylePrivate::Button_WindowClose }, + { QStyle::SC_TitleBarMinButton, QMacStylePrivate::Button_WindowMiniaturize }, + { QStyle::SC_TitleBarMaxButton, QMacStylePrivate::Button_WindowZoom } + }; + + for (const auto &wb : buttons) + if (wb.sc == sc) + return wb.ct; + + return NoControl; +} + + #if QT_CONFIG(tabbar) void QMacStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const { @@ -1904,6 +1959,37 @@ NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const case Button_RadioButton: bv = makeButton(NSRadioButton, NSRegularSquareBezelStyle); break; + case Button_WindowClose: + case Button_WindowMiniaturize: + case Button_WindowZoom: { + const NSWindowButton button = [=] { + switch (widget.first) { + case Button_WindowClose: + return NSWindowCloseButton; + case Button_WindowMiniaturize: + return NSWindowMiniaturizeButton; + case Button_WindowZoom: + return NSWindowZoomButton; + default: + break; + } + Q_UNREACHABLE(); + } (); +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12) + const auto styleMask = NSWindowStyleMaskTitled + | NSWindowStyleMaskClosable + | NSWindowStyleMaskMiniaturizable + | NSWindowStyleMaskResizable; +#else + const auto styleMask = NSTitledWindowMask + | NSClosableWindowMask + | NSMiniaturizableWindowMask + | NSResizableWindowMask; +#endif + bv = [NSWindow standardWindowButton:button forStyleMask:styleMask]; + [bv retain]; + break; + } case ComboBox: bv = [[NSComboBox alloc] init]; break; @@ -2229,15 +2315,20 @@ void QMacStyle::unpolish(QApplication *) void QMacStyle::polish(QWidget* w) { + if (false #if QT_CONFIG(menu) - if (qobject_cast<QMenu*>(w) -#if QT_CONFIG(combobox) - || qobject_cast<QComboBoxPrivateContainer *>(w) + || qobject_cast<QMenu*>(w) +# if QT_CONFIG(combobox) + || qobject_cast<QComboBoxPrivateContainer *>(w) +# endif #endif - ) { +#if QT_CONFIG(mdiarea) + || qobject_cast<QMdiSubWindow *>(w) +#endif + ) { w->setAttribute(Qt::WA_TranslucentBackground, true); + w->setAutoFillBackground(false); } -#endif #if QT_CONFIG(tabbar) if (QTabBar *tb = qobject_cast<QTabBar*>(w)) { @@ -2409,14 +2500,6 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW break; case PM_SpinBoxFrameWidth: ret = qt_mac_aqua_get_metric(EditTextFrameOutset); - switch (d->aquaSizeConstrain(opt, widget)) { - case QStyleHelper::SizeMini: - ret += 1; - break; - default: - ret += 2; - break; - } break; case PM_ButtonShiftHorizontal: case PM_ButtonShiftVertical: @@ -2923,19 +3006,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w ret = true; break; case SH_WindowFrame_Mask: - ret = 1; - if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(hret)) { - mask->region = opt->rect; - mask->region -= QRect(opt->rect.left(), opt->rect.top(), 5, 1); - mask->region -= QRect(opt->rect.left(), opt->rect.top() + 1, 3, 1); - mask->region -= QRect(opt->rect.left(), opt->rect.top() + 2, 2, 1); - mask->region -= QRect(opt->rect.left(), opt->rect.top() + 3, 1, 2); - - mask->region -= QRect(opt->rect.right() - 4, opt->rect.top(), 5, 1); - mask->region -= QRect(opt->rect.right() - 2, opt->rect.top() + 1, 3, 1); - mask->region -= QRect(opt->rect.right() - 1, opt->rect.top() + 2, 2, 1); - mask->region -= QRect(opt->rect.right() , opt->rect.top() + 3, 1, 2); - } + ret = false; break; case SH_TabBar_ElideMode: ret = Qt::ElideRight; @@ -3023,6 +3094,9 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w case SH_ComboBox_AllowWheelScrolling: ret = false; break; + case SH_SpinBox_ButtonsInsideFrame: + ret = false; + break; default: ret = QCommonStyle::styleHint(sh, opt, w, hret); break; @@ -3215,6 +3289,15 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai } break; case PE_FrameWindow: + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + if (w && w->inherits("QMdiSubWindow")) { + p->save(); + p->setPen(QPen(frame->palette.dark().color(), frame->lineWidth)); + p->setBrush(frame->palette.window()); + p->drawRect(frame->rect); + p->restore(); + } + } break; case PE_IndicatorDockWidgetResizeHandle: { // The docwidget resize handle is drawn as a one-pixel wide line. @@ -3489,31 +3572,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai p->setPen(Qt::transparent); p->setBrush(opt->palette.window()); p->setRenderHint(QPainter::Antialiasing, true); - QPainterPath path; - static const qreal CornerPointOffset = 5.5; - static const qreal CornerControlOffset = 2.1; - QRectF r = opt->rect; - // Top-left corner - path.moveTo(r.left(), r.top() + CornerPointOffset); - path.cubicTo(r.left(), r.top() + CornerControlOffset, - r.left() + CornerControlOffset, r.top(), - r.left() + CornerPointOffset, r.top()); - // Top-right corner - path.lineTo(r.right() - CornerPointOffset, r.top()); - path.cubicTo(r.right() - CornerControlOffset, r.top(), - r.right(), r.top() + CornerControlOffset, - r.right(), r.top() + CornerPointOffset); - // Bottom-right corner - path.lineTo(r.right(), r.bottom() - CornerPointOffset); - path.cubicTo(r.right(), r.bottom() - CornerControlOffset, - r.right() - CornerControlOffset, r.bottom(), - r.right() - CornerPointOffset, r.bottom()); - // Bottom-right corner - path.lineTo(r.left() + CornerPointOffset, r.bottom()); - path.cubicTo(r.left() + CornerControlOffset, r.bottom(), - r.left(), r.bottom() - CornerControlOffset, - r.left(), r.bottom() - CornerPointOffset); - path.lineTo(r.left(), r.top() + CornerPointOffset); + const QPainterPath path = d->windowPanelPath(opt->rect); p->drawPath(path); p->restore(); } break; @@ -4074,78 +4133,41 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter #endif #if QT_CONFIG(dockwidget) case CE_DockWidgetTitle: - if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(w)) { - bool floating = dockWidget->isFloating(); - if (floating) { - ThemeDrawState tds = d->getDrawState(opt->state); - HIThemeWindowDrawInfo wdi; - wdi.version = qt_mac_hitheme_version; - wdi.state = tds; - wdi.windowType = kThemeMovableDialogWindow; - wdi.titleHeight = opt->rect.height(); - wdi.titleWidth = opt->rect.width(); - wdi.attributes = 0; - - CGRect titleBarRect; - CGRect tmpRect = opt->rect.toCGRect(); - { - QCFType<HIShapeRef> titleRegion; - QRect newr = opt->rect.adjusted(0, 0, 2, 0); - HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion); - HIShapeGetBounds(titleRegion, &tmpRect); - newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y)); - titleBarRect = newr.toCGRect(); - } - QMacCGContext cg(p); - HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0); - } else { - // fill title bar background - QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom()); - linearGrad.setColorAt(0, mainWindowGradientBegin); - linearGrad.setColorAt(1, mainWindowGradientEnd); - p->fillRect(opt->rect, linearGrad); - - // draw horizontal lines at top and bottom - p->save(); - p->setPen(mainWindowGradientBegin.lighter(114)); - p->drawLine(opt->rect.topLeft(), opt->rect.topRight()); - p->setPen(mainWindowGradientEnd.darker(114)); - p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight()); - p->restore(); + if (const auto *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) { + const bool isVertical = dwOpt->verticalTitleBar; + const auto effectiveRect = isVertical ? opt->rect.transposed() : opt->rect; + p->save(); + if (isVertical) { + p->translate(effectiveRect.left(), effectiveRect.top() + effectiveRect.width()); + p->rotate(-90); + p->translate(-effectiveRect.left(), -effectiveRect.top()); } - } - - // Draw the text... - if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) { - if (!dwOpt->title.isEmpty()) { - - const bool verticalTitleBar = dwOpt->verticalTitleBar; - - QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, w); - if (verticalTitleBar) { - QRect rect = dwOpt->rect; - QRect r = rect.transposed(); - titleRect = QRect(r.left() + rect.bottom() - - titleRect.bottom(), - r.top() + titleRect.left() - rect.left(), - titleRect.height(), titleRect.width()); + // fill title bar background + QLinearGradient linearGrad; + linearGrad.setStart(QPointF(0, 0)); + linearGrad.setFinalStop(QPointF(0, 2 * effectiveRect.height())); + linearGrad.setColorAt(0, opt->palette.button().color()); + linearGrad.setColorAt(1, opt->palette.dark().color()); + p->fillRect(effectiveRect, linearGrad); - p->translate(r.left(), r.top() + r.width()); - p->rotate(-90); - p->translate(-r.left(), -r.top()); - } + // draw horizontal line at bottom + p->setPen(opt->palette.dark().color()); + p->drawLine(effectiveRect.bottomLeft(), effectiveRect.bottomRight()); - QFont oldFont = p->font(); - p->setFont(qt_app_fonts_hash()->value("QToolButton", p->font())); - QString text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, - titleRect.width()); - drawItemText(p, titleRect, - Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette, - dwOpt->state & State_Enabled, text, - QPalette::WindowText); - p->setFont(oldFont); + if (!dwOpt->title.isEmpty()) { + auto titleRect = proxy()->subElementRect(SE_DockWidgetTitleBarText, opt, w); + if (isVertical) + titleRect = QRect(effectiveRect.left() + opt->rect.bottom() - titleRect.bottom(), + effectiveRect.top() + titleRect.left() - opt->rect.left(), + titleRect.height(), + titleRect.width()); + + const auto text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width()); + proxy()->drawItemText(p, titleRect, Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette, + dwOpt->state & State_Enabled, text, QPalette::WindowText); } + p->restore(); } break; #endif @@ -4543,28 +4565,22 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter #if QT_CONFIG(mainwindow) if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) { if (toolBar && toolBar->toolBarArea == Qt::TopToolBarArea && mainWindow->unifiedTitleAndToolBarOnMac()) { - // fill with transparent pixels. p->save(); p->setCompositionMode(QPainter::CompositionMode_Source); p->fillRect(opt->rect, Qt::transparent); p->restore(); - // Drow a horizontal sepearator line at the toolBar bottom if the "unified" area ends here. + // Drow a horizontal separator line at the toolBar bottom if the "unified" area ends here. // There might be additional toolbars or other widgets such as tab bars in document // mode below. Determine this by making a unified toolbar area test for the row below // this toolbar. - QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft()); - bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1); + const QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft()); + const bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1); if (isEndOfUnifiedArea) { - int margin; - margin = qt_mac_aqua_get_metric(SeparatorSize); - CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin); - HIThemeSeparatorDrawInfo separatorDrawInfo; - separatorDrawInfo.version = 0; - separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive; - QMacCGContext cg(p); - HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal); + const int margin = qt_mac_aqua_get_metric(SeparatorSize); + const auto separatorRect = QRect(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin); + p->fillRect(separatorRect, opt->palette.dark().color()); } break; } @@ -5446,19 +5462,16 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex case CC_SpinBox: if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) { - int frame_size; - frame_size = qt_mac_aqua_get_metric(EditTextFrameOutset); - - QRect lineeditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget); - lineeditRect.adjust(-frame_size, -frame_size, +frame_size, +frame_size); - - HIThemeFrameDrawInfo fdi; - fdi.version = qt_mac_hitheme_version; - fdi.state = tds == kThemeStateInactive ? kThemeStateActive : tds; - fdi.kind = kHIThemeFrameTextFieldSquare; - fdi.isFocused = false; - CGRect cgRect = lineeditRect.toCGRect(); - HIThemeDrawFrame(&cgRect, &fdi, cg, kHIThemeOrientationNormal); + const auto lineEditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget); + QStyleOptionFrame frame; + static_cast<QStyleOption &>(frame) = *opt; + frame.rect = lineEditRect; + frame.state |= State_Sunken; + frame.lineWidth = 1; + frame.midLineWidth = 0; + frame.features = QStyleOptionFrame::None; + frame.frameShape = QFrame::Box; + drawPrimitive(PE_FrameLineEdit, &frame, p, widget); } if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) { const QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget) @@ -5476,7 +5489,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex const bool upPressed = sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken); const bool downPressed = sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken); const CGFloat x = CGRectGetMidX(newRect); - const CGFloat y = upPressed ? -3 : 3; // FIXME Weird coordinate shift going on + const CGFloat y = upPressed ? -3 : 3; // Weird coordinate shift going on. Verified with Hopper const CGPoint pressPoint = CGPointMake(x, y); // Pretend we're pressing the mouse on the right button. Unfortunately, NSStepperCell has no // API to highlight a specific button. The highlighted property works only on the down button. @@ -5513,115 +5526,74 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex } break; case CC_TitleBar: - if (const QStyleOptionTitleBar *titlebar - = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { - if (titlebar->state & State_Active) { - if (titlebar->titleBarState & State_Active) - tds = kThemeStateActive; - else - tds = kThemeStateInactive; + if (const auto *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + const bool isActive = (titlebar->state & State_Active) + && (titlebar->titleBarState & State_Active); + + p->fillRect(opt->rect, Qt::transparent); + p->setRenderHint(QPainter::Antialiasing); + p->setClipRect(opt->rect, Qt::IntersectClip); + + // FIXME A single drawPath() with 0-sized pen + // doesn't look as good as this double fillPath(). + const auto outterFrameRect = QRectF(opt->rect.adjusted(0, 0, 0, opt->rect.height())); + QPainterPath outterFramePath = d->windowPanelPath(outterFrameRect); + p->fillPath(outterFramePath, opt->palette.dark()); + + const auto frameAdjust = 1.0 / p->device()->devicePixelRatioF(); + const auto innerFrameRect = outterFrameRect.adjusted(frameAdjust, frameAdjust, -frameAdjust, 0); + QPainterPath innerFramePath = d->windowPanelPath(innerFrameRect); + if (isActive) { + QLinearGradient g; + g.setStart(QPointF(0, 0)); + g.setFinalStop(QPointF(0, 2 * opt->rect.height())); + g.setColorAt(0, opt->palette.button().color()); + g.setColorAt(1, opt->palette.dark().color()); + p->fillPath(innerFramePath, g); } else { - tds = kThemeStateInactive; + p->fillPath(innerFramePath, opt->palette.button()); } - HIThemeWindowDrawInfo wdi; - wdi.version = qt_mac_hitheme_version; - wdi.state = tds; - wdi.windowType = QtWinType; - wdi.titleHeight = titlebar->rect.height(); - wdi.titleWidth = titlebar->rect.width(); - wdi.attributes = kThemeWindowHasTitleText; - // It seems HIThemeDrawTitleBarWidget is not able to draw a dirty - // close button, so use HIThemeDrawWindowFrame instead. - if (widget && widget->isWindowModified() && titlebar->subControls & SC_TitleBarCloseButton) - wdi.attributes |= kThemeWindowHasCloseBox | kThemeWindowHasDirty; - - CGRect titleBarRect; - CGRect tmpRect = titlebar->rect.toCGRect(); - { - QCFType<HIShapeRef> titleRegion; - QRect newr = titlebar->rect.adjusted(0, 0, 2, 0); - HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion); - HIShapeGetBounds(titleRegion, &tmpRect); - newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y)); - titleBarRect = newr.toCGRect(); - } - HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0); if (titlebar->subControls & (SC_TitleBarCloseButton | SC_TitleBarMaxButton | SC_TitleBarMinButton | SC_TitleBarNormalButton)) { - HIThemeWindowWidgetDrawInfo wwdi; - wwdi.version = qt_mac_hitheme_version; - wwdi.widgetState = tds; - if (titlebar->state & State_MouseOver) - wwdi.widgetState = kThemeStateRollover; - wwdi.windowType = QtWinType; - wwdi.attributes = wdi.attributes | kThemeWindowHasFullZoom | kThemeWindowHasCloseBox | kThemeWindowHasCollapseBox; - wwdi.windowState = wdi.state; - wwdi.titleHeight = wdi.titleHeight; - wwdi.titleWidth = wdi.titleWidth; - ThemeDrawState savedControlState = wwdi.widgetState; - uint sc = SC_TitleBarMinButton; - ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox; - bool active = titlebar->state & State_Active; - - while (sc <= SC_TitleBarCloseButton) { - if (sc & titlebar->subControls) { - uint tmp = sc; - wwdi.widgetState = savedControlState; - wwdi.widgetType = tbw; - if (sc == SC_TitleBarMinButton) - tmp |= SC_TitleBarNormalButton; - if (active && (titlebar->activeSubControls & tmp) - && (titlebar->state & State_Sunken)) - wwdi.widgetState = kThemeStatePressed; - // Draw all sub controllers except the dirty close button - // (it is already handled by HIThemeDrawWindowFrame). - if (!(widget && widget->isWindowModified() && tbw == kThemeWidgetCloseBox)) { - HIThemeDrawTitleBarWidget(&titleBarRect, &wwdi, cg, kHIThemeOrientationNormal); - p->paintEngine()->syncState(); - } - } - sc = sc << 1; - tbw = tbw >> 1; + const bool isHovered = (titlebar->state & State_MouseOver); + static const SubControl buttons[] = { + SC_TitleBarCloseButton, SC_TitleBarMinButton, SC_TitleBarMaxButton + }; + for (const auto sc : buttons) { + const auto ct = d->windowButtonCocoaControl(sc); + const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge); + auto *wb = static_cast<NSButton *>(d->cocoaControl(cw)); + wb.enabled = (sc & titlebar->subControls); + [wb highlight:(titlebar->state & State_Sunken) && (sc & titlebar->activeSubControls)]; + Q_UNUSED(isHovered); // FIXME No public API for this + + const auto buttonRect = proxy()->subControlRect(CC_TitleBar, titlebar, sc, widget); + const auto drawBlock = ^ (CGContextRef ctx, const CGRect &rect) { + Q_UNUSED(ctx); + Q_UNUSED(rect); + auto *wbCell = static_cast<NSButtonCell *>(wb.cell); + [wbCell drawWithFrame:rect inView:wb]; + }; + d->drawNSViewInRect(cw, wb, buttonRect, p, widget != nullptr, drawBlock); } } - p->paintEngine()->syncState(); + if (titlebar->subControls & SC_TitleBarLabel) { - int iw = 0; + const auto tr = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarLabel, widget); if (!titlebar->icon.isNull()) { - QCFType<HIShapeRef> titleRegion2; - HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleProxyIconRgn, - &titleRegion2); - HIShapeGetBounds(titleRegion2, &tmpRect); - if (tmpRect.size.width != 1) { - int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); - iw = titlebar->icon.actualSize(QSize(iconExtent, iconExtent)).width(); - } - } - if (!titlebar->text.isEmpty()) { - p->save(); - QCFType<HIShapeRef> titleRegion3; - HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleTextRgn, &titleRegion3); - HIShapeGetBounds(titleRegion3, &tmpRect); - p->setClipRect(QRectF::fromCGRect(tmpRect).toRect()); - QRect br = p->clipRegion().boundingRect(); - int x = br.x(), - y = br.y() + (titlebar->rect.height() / 2 - p->fontMetrics().height() / 2); - if (br.width() <= (p->fontMetrics().horizontalAdvance(titlebar->text) + iw * 2)) - x += iw; - else - x += br.width() / 2 - p->fontMetrics().horizontalAdvance(titlebar->text) / 2; - if (iw) { - int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); - p->drawPixmap(x - iw, y, - titlebar->icon.pixmap(window, QSize(iconExtent, iconExtent), QIcon::Normal)); - } - drawItemText(p, br, Qt::AlignCenter, opt->palette, tds == kThemeStateActive, - titlebar->text, QPalette::Text); - p->restore(); + const auto iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + const auto iconSize = QSize(iconExtent, iconExtent); + const auto iconPos = tr.x() - titlebar->icon.actualSize(iconSize).width() - qRound(titleBarIconTitleSpacing); + // Only render the icon if it'll be fully visible + if (iconPos < tr.right() - titleBarIconTitleSpacing) + p->drawPixmap(iconPos, tr.y(), titlebar->icon.pixmap(window, iconSize, QIcon::Normal)); } + + if (!titlebar->text.isEmpty()) + drawItemText(p, tr, Qt::AlignCenter, opt->palette, isActive, titlebar->text, QPalette::Text); } } break; @@ -5868,50 +5840,6 @@ QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc, } } break; -/* - I don't know why, but we only get kWindowContentRgn here, which isn't what we want at all. - It would be very nice if this would work. - case QStyle::CC_TitleBar: - if (const QStyleOptionTitleBar *tbar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { - HIThemeWindowDrawInfo wdi; - memset(&wdi, 0, sizeof(wdi)); - wdi.version = qt_mac_hitheme_version; - wdi.state = kThemeStateActive; - wdi.windowType = QtWinType; - wdi.titleWidth = tbar->rect.width(); - wdi.titleHeight = tbar->rect.height(); - if (tbar->titleBarState) - wdi.attributes |= kThemeWindowHasFullZoom | kThemeWindowHasCloseBox - | kThemeWindowHasCollapseBox; - else if (tbar->titleBarFlags & Qt::WindowSystemMenuHint) - wdi.attributes |= kThemeWindowHasCloseBox; - QRect tmpRect = tbar->rect; - tmpRect.setHeight(tmpRect.height() + 100); - CGRect cgRect = tmpRect.toCGRect(); - WindowRegionCode hit; - CGPoint hipt = CGPointMake(pt.x(), pt.y()); - if (HIThemeGetWindowRegionHit(&cgRect, &wdi, &hipt, &hit)) { - switch (hit) { - case kWindowCloseBoxRgn: - sc = QStyle::SC_TitleBarCloseButton; - break; - case kWindowCollapseBoxRgn: - sc = QStyle::SC_TitleBarMinButton; - break; - case kWindowZoomBoxRgn: - sc = QStyle::SC_TitleBarMaxButton; - break; - case kWindowTitleTextRgn: - sc = QStyle::SC_TitleBarLabel; - break; - default: - qDebug("got something else %d", hit); - break; - } - } - } - break; -*/ default: sc = QCommonStyle::hitTestComplexControl(cc, opt, pt, widget); break; @@ -6005,49 +5933,47 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op } break; case CC_TitleBar: - if (const QStyleOptionTitleBar *titlebar - = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { - HIThemeWindowDrawInfo wdi; - memset(&wdi, 0, sizeof(wdi)); - wdi.version = qt_mac_hitheme_version; - wdi.state = kThemeStateActive; - wdi.windowType = QtWinType; - wdi.titleHeight = titlebar->rect.height(); - wdi.titleWidth = titlebar->rect.width(); - wdi.attributes = kThemeWindowHasTitleText; - if (titlebar->subControls & SC_TitleBarCloseButton) - wdi.attributes |= kThemeWindowHasCloseBox; - if (titlebar->subControls & SC_TitleBarMaxButton - | SC_TitleBarNormalButton) - wdi.attributes |= kThemeWindowHasFullZoom; - if (titlebar->subControls & SC_TitleBarMinButton) - wdi.attributes |= kThemeWindowHasCollapseBox; - WindowRegionCode wrc = kWindowGlobalPortRgn; - - if (sc == SC_TitleBarCloseButton) - wrc = kWindowCloseBoxRgn; - else if (sc == SC_TitleBarMinButton) - wrc = kWindowCollapseBoxRgn; - else if (sc == SC_TitleBarMaxButton) - wrc = kWindowZoomBoxRgn; - else if (sc == SC_TitleBarLabel) - wrc = kWindowTitleTextRgn; - else if (sc == SC_TitleBarSysMenu) - ret.setRect(-1024, -1024, 10, proxy()->pixelMetric(PM_TitleBarHeight, - titlebar, widget)); - if (wrc != kWindowGlobalPortRgn) { - QCFType<HIShapeRef> region; - QRect tmpRect = titlebar->rect; - CGRect titleRect = tmpRect.toCGRect(); - HIThemeGetWindowShape(&titleRect, &wdi, kWindowTitleBarRgn, ®ion); - HIShapeGetBounds(region, &titleRect); - CFRelease(region); - tmpRect.translate(tmpRect.x() - int(titleRect.origin.x), - tmpRect.y() - int(titleRect.origin.y)); - titleRect = tmpRect.toCGRect(); - HIThemeGetWindowShape(&titleRect, &wdi, wrc, ®ion); - HIShapeGetBounds(region, &titleRect); - ret = QRectF::fromCGRect(titleRect).toRect(); + if (const auto *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + // The title bar layout is as follows: close, min, zoom, icon, title + // [ x _ + @ Window Title ] + // Center the icon and title until it starts to overlap with the buttons. + // The icon doesn't count towards SC_TitleBarLabel, but it's still rendered + // next to the title text. See drawComplexControl(). + if (sc == SC_TitleBarLabel) { + qreal labelWidth = titlebar->fontMetrics.horizontalAdvance(titlebar->text) + 1; // FIXME Rounding error? + qreal labelHeight = titlebar->fontMetrics.height(); + + const auto lastButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarMaxButton, widget); + qreal controlsSpacing = lastButtonRect.right() + titleBarButtonSpacing; + if (!titlebar->icon.isNull()) { + const auto iconSize = proxy()->pixelMetric(PM_SmallIconSize); + const auto actualIconSize = titlebar->icon.actualSize(QSize(iconSize, iconSize)).width();; + controlsSpacing += actualIconSize + titleBarIconTitleSpacing; + } + + const qreal labelPos = qMax(controlsSpacing, (opt->rect.width() - labelWidth) / 2.0); + labelWidth = qMin(labelWidth, opt->rect.width() - (labelPos + titleBarTitleRightMargin)); + ret = QRect(labelPos, (opt->rect.height() - labelHeight) / 2, + labelWidth, labelHeight); + } else { + const auto currentButton = d->windowButtonCocoaControl(sc); + if (currentButton == QMacStylePrivate::NoControl) + break; + + QPointF buttonPos = titlebar->rect.topLeft() + QPointF(titleBarButtonSpacing, 0); + QSizeF buttonSize; + for (int ct = QMacStylePrivate::Button_WindowClose; ct <= currentButton; ct++) { + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::CocoaControlType(ct), + QStyleHelper::SizeLarge); + auto *wb = static_cast<NSButton *>(d->cocoaControl(cw)); + if (ct == currentButton) + buttonSize = QSizeF::fromCGSize(wb.frame.size); + else + buttonPos.rx() += wb.frame.size.width + titleBarButtonSpacing; + } + + const auto vOffset = (opt->rect.height() - buttonSize.height()) / 2.0; + ret = QRectF(buttonPos, buttonSize).translated(0, vOffset).toRect(); } } break; @@ -6178,9 +6104,9 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op case CC_SpinBox: if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { QStyleHelper::WidgetSizePolicy aquaSize = d->effectiveAquaSizeConstrain(spin, widget); + const auto fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget); int spinner_w; int spinBoxSep; - int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget); switch (aquaSize) { case QStyleHelper::SizeLarge: spinner_w = 14; @@ -6243,16 +6169,11 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op break; } case SC_SpinBoxEditField: - if (spin->buttonSymbols == QAbstractSpinBox::NoButtons) { - ret.setRect(fw, fw, - spin->rect.width() - fw * 2, - spin->rect.height() - fw * 2); - } else { - ret.setRect(fw, fw, - spin->rect.width() - fw * 2 - spinBoxSep - spinner_w, - spin->rect.height() - fw * 2); + ret = spin->rect.adjusted(fw, fw, -fw, -fw); + if (spin->buttonSymbols != QAbstractSpinBox::NoButtons) { + ret.setWidth(spin->rect.width() - spinBoxSep - spinner_w); + ret = visualRect(spin->direction, spin->rect, ret); } - ret = visualRect(spin->direction, spin->rect, ret); break; default: ret = QCommonStyle::subControlRect(cc, spin, sc, widget); @@ -6289,10 +6210,8 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, #if QT_CONFIG(spinbox) case CT_SpinBox: if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { - // Add button + frame widths - int buttonWidth = 20; - int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget); - sz += QSize(buttonWidth + 2*fw, 2*fw - 3); + const int buttonWidth = 20; // FIXME Use subControlRect() + sz += QSize(buttonWidth, -3); } break; #endif @@ -6635,24 +6554,14 @@ bool QMacStyle::event(QEvent *e) } } #endif + if (focusWidget && focusWidget->testAttribute(Qt::WA_MacShowFocusRect)) { - f = focusWidget; - QWidget *top = f->parentWidget(); - while (top && !top->isWindow() && !(top->windowType() == Qt::SubWindow)) - top = top->parentWidget(); -#if QT_CONFIG(mainwindow) - if (qobject_cast<QMainWindow *>(top)) { - QWidget *central = static_cast<QMainWindow *>(top)->centralWidget(); - for (const QWidget *par = f; par; par = par->parentWidget()) { - if (par == central) { - top = central; - break; - } - if (par->isWindow()) - break; - } - } +#if QT_CONFIG(spinbox) + if (const auto sb = qobject_cast<QAbstractSpinBox *>(focusWidget)) + f = sb->property("_q_spinbox_lineedit").value<QWidget *>(); + else #endif + f = focusWidget; } if (f) { if(!d->focusWidget) diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index 02f74294d1..00dc8a9b53 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -182,6 +182,7 @@ class QMacStylePrivate : public QCommonStylePrivate Q_DECLARE_PUBLIC(QMacStyle) public: enum CocoaControlType { + NoControl, // For when there's no such a control in Cocoa Box, // QGroupBox Button_CheckBox, Button_Disclosure, // Disclosure triangle, like in QTreeView @@ -189,6 +190,9 @@ public: Button_PullDown, // QPushButton with menu Button_PushButton, Button_RadioButton, + Button_WindowClose, + Button_WindowMiniaturize, + Button_WindowZoom, ComboBox, // Editable QComboBox ProgressIndicator_Determinate, ProgressIndicator_Indeterminate, @@ -275,6 +279,10 @@ public: void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const; void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const; + QPainterPath windowPanelPath(const QRectF &r) const; + + CocoaControlType windowButtonCocoaControl(QStyle::SubControl sc) const; + #if QT_CONFIG(tabbar) void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const; #endif diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index 88957b0f94..4700ee29bf 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -26,7 +26,7 @@ qhp.QtWidgets.subprojects.classes.sortPages = true tagfile = ../../../doc/qtwidgets/qtwidgets.tags -depends += qtcore qtgui qtdoc qtsql qtdesigner qtquick qmake qtplatformheaders qtsvg +depends += qtcore qtgui qtdoc qtsql qtdesigner qtquick qmake qtplatformheaders qtsvg qtlinguist headerdirs += .. diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 7f027595b7..6777b09043 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -980,9 +980,18 @@ void QListView::paintEvent(QPaintEvent *e) ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing() : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing(); + const int rowCount = d->commonListView->rowCount(); QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd(); for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) { Q_ASSERT((*it).isValid()); + if (rowCount == 1) + option.viewItemPosition = QStyleOptionViewItem::OnlyOne; + else if ((*it).row() == 0) + option.viewItemPosition = QStyleOptionViewItem::Beginning; + else if ((*it).row() == rowCount - 1) + option.viewItemPosition = QStyleOptionViewItem::End; + else + option.viewItemPosition = QStyleOptionViewItem::Middle; option.rect = visualRect(*it); if (flow() == TopToBottom) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 5eab2d1038..bc5062e942 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -11219,10 +11219,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) case Qt::WA_NoChildEventsFromChildren: d->receiveChildEvents = !on; break; - case Qt::WA_MacBrushedMetal: #if 0 // Used to be included in Qt4 for Q_WS_MAC - d->setStyle_helper(style(), false, true); // Make sure things get unpolished/polished correctly. - // fall through since changing the metal attribute affects the opaque size grip. case Qt::WA_MacOpaqueSizeGrip: d->macUpdateOpaqueSizeGrip(); break; @@ -11235,12 +11232,10 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) case Qt::WA_Hover: qt_mac_update_mouseTracking(this); break; -#endif case Qt::WA_MacAlwaysShowToolWindow: -#if 0 // Used to be included in Qt4 for Q_WS_MAC d->macUpdateHideOnSuspend(); -#endif break; +#endif case Qt::WA_MacNormalSize: case Qt::WA_MacSmallSize: case Qt::WA_MacMiniSize: diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 1276eef1d1..670a23e78f 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -5302,6 +5302,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget case SH_ComboBox_AllowWheelScrolling: ret = true; break; + case SH_SpinBox_ButtonsInsideFrame: + ret = true; + break; default: ret = 0; break; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index c22f45d54e..73a6554f1a 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1997,6 +1997,10 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, This is on by default in all styles except the Mac style. This enum value has been introduced in Qt 5.10. + \value SH_SpinBox_ButtonsInsideFrame + Determnines if the spin box buttons are inside the line edit frame. + This enum value has been introduced in Qt 5.11. + \sa styleHint() */ diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index ab61534a96..cef569d514 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -740,6 +740,7 @@ public: SH_TitleBar_ShowToolTipsOnButtons, SH_Widget_Animation_Duration, SH_ComboBox_AllowWheelScrolling, + SH_SpinBox_ButtonsInsideFrame, // Add new style hint values here SH_CustomBase = 0xf0000000 diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 61526916f1..7ca47e9f0f 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -678,15 +678,20 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit) Q_ASSERT(lineEdit); return; } + + if (lineEdit == d->edit) + return; + delete d->edit; d->edit = lineEdit; + setProperty("_q_spinbox_lineedit", QVariant::fromValue<QWidget *>(d->edit)); if (!d->edit->validator()) d->edit->setValidator(d->validator); if (d->edit->parent() != this) d->edit->setParent(this); - d->edit->setFrame(false); + d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this)); d->edit->setFocusProxy(this); d->edit->setAcceptDrops(false); @@ -818,6 +823,8 @@ void QAbstractSpinBox::changeEvent(QEvent *event) d->spinClickTimerInterval = style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate, 0, this); d->spinClickThresholdTimerInterval = style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, 0, this); + if (d->edit) + d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this)); d->reset(); d->updateEditFieldGeometry(); break; @@ -1644,7 +1651,9 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const option->initFrom(this); option->activeSubControls = QStyle::SC_None; option->buttonSymbols = d->buttonSymbols; - option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField; + option->subControls = QStyle::SC_SpinBoxEditField; + if (!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this)) + option->subControls |= QStyle::SC_SpinBoxFrame; if (d->buttonSymbols != QAbstractSpinBox::NoButtons) { option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown; if (d->buttonState & Up) { diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index ac76217ece..e17c2c1f4c 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -653,6 +653,8 @@ void QDockWidgetPrivate::init() QObject::connect(button, SIGNAL(clicked()), q, SLOT(close())); layout->setWidgetForRole(QDockWidgetLayout::CloseButton, button); + font = QApplication::font("QDockWidgetTitle"); + #ifndef QT_NO_ACTION toggleViewAction = new QAction(q); toggleViewAction->setCheckable(true); @@ -685,6 +687,7 @@ void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const // If we are in a floating tab, init from the parent because the attributes and the geometry // of the title bar should be taken from the floating window. option->initFrom(floatingTab && !isFloating() ? parentWidget() : this); + option->fontMetrics = QFontMetrics(d->font); option->rect = dwlayout->titleArea(); option->title = d->fixedWindowTitle; option->closable = hasFeature(this, QDockWidget::DockWidgetClosable); @@ -1481,6 +1484,7 @@ void QDockWidget::paintEvent(QPaintEvent *event) // the title may wish to extend out to all sides (eg. Vista style) QStyleOptionDockWidget titleOpt; initStyleOption(&titleOpt); + p.setFont(d_func()->font); p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt); } } diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h index e35fd17fc2..766e4ed161 100644 --- a/src/widgets/widgets/qdockwidget_p.h +++ b/src/widgets/widgets/qdockwidget_p.h @@ -99,6 +99,8 @@ public: QDockWidget::DockWidgetFeatures features; Qt::DockWidgetAreas allowedAreas; + QFont font; + #ifndef QT_NO_ACTION QAction *toggleViewAction; #endif diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index 0fdeaeb1e6..794674c427 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -1986,6 +1986,13 @@ void QMdiSubWindowPrivate::updateActions() for (int i = 0; i < NumWindowStateActions; ++i) setVisible(WindowStateAction(i), false); +#ifdef Q_OS_MACOS + if (q_func()->style()->inherits("QMacStyle")) + for (int i = 0; i < NumWindowStateActions; ++i) + if (QAction *action = actions[i]) + action->setIconVisibleInMenu(false); +#endif + if (windowFlags & Qt::FramelessWindowHint) return; diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 9eb8071ff3..0780fb9172 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -1103,8 +1103,9 @@ void tst_QVariant::toString_data() QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" ); - QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" ); - QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56" ); + QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56.000" ); + QTest::newRow( "qtime-with-ms" ) << QVariant( QTime( 12, 34, 56, 789 ) ) << QString( "12:34:56.789" ); + QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56, 789 ) ) ) << QString( "2002-01-01T12:34:56.789" ); QTest::newRow( "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) << QString( "123456789012" ); QTest::newRow("QJsonValue") << QVariant(QJsonValue(QString("hello"))) << QString("hello"); @@ -1155,6 +1156,7 @@ void tst_QVariant::toTime_data() QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QTime( 12, 34, 56 ); QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) << QTime( 12, 34, 56 ); QTest::newRow( "qstring" ) << QVariant( QString( "12:34:56" ) ) << QTime( 12, 34, 56 ); + QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "12:34:56.789" ) ) << QTime( 12, 34, 56, 789 ); } void tst_QVariant::toTime() @@ -1175,6 +1177,10 @@ void tst_QVariant::toDateTime_data() << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) ); QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); + QTest::newRow( "qstring-utc" ) << QVariant( QString( "2002-10-10T12:34:56Z" ) ) + << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ), Qt::UTC ); + QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "2002-10-10T12:34:56.789" ) ) + << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56, 789 ) ); } void tst_QVariant::toDateTime() diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp index 9e3edc96ec..bad72c081b 100644 --- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp +++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp @@ -124,8 +124,16 @@ void tst_QUuid::fromChar() void tst_QUuid::toString() { QCOMPARE(uuidA.toString(), QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + QCOMPARE(uuidA.toString(QUuid::WithoutBraces), + QString("fc69b59e-cc34-4436-a43c-ee95d128b8c5")); + QCOMPARE(uuidA.toString(QUuid::Id128), + QString("fc69b59ecc344436a43cee95d128b8c5")); QCOMPARE(uuidB.toString(), QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")); + QCOMPARE(uuidB.toString(QUuid::WithoutBraces), + QString("1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b")); + QCOMPARE(uuidB.toString(QUuid::Id128), + QString("1ab6e93ab1cb4a87ba47ec7e99039a7b")); } void tst_QUuid::fromString_data() @@ -185,8 +193,16 @@ void tst_QUuid::fromString() void tst_QUuid::toByteArray() { QCOMPARE(uuidA.toByteArray(), QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + QCOMPARE(uuidA.toByteArray(QUuid::WithoutBraces), + QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5")); + QCOMPARE(uuidA.toByteArray(QUuid::Id128), + QByteArray("fc69b59ecc344436a43cee95d128b8c5")); QCOMPARE(uuidB.toByteArray(), QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")); + QCOMPARE(uuidB.toByteArray(QUuid::WithoutBraces), + QByteArray("1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b")); + QCOMPARE(uuidB.toByteArray(QUuid::Id128), + QByteArray("1ab6e93ab1cb4a87ba47ec7e99039a7b")); } void tst_QUuid::fromByteArray() diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h index 701da7d346..97397e3159 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h +++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h @@ -220,79 +220,59 @@ public: bool addDbs() { - //addDb("QOCI", "localhost", "system", "penandy"); -// addDb( "QOCI8", "//horsehead.qt-project.org:1521/pony.troll.no", "scott", "tiger" ); // Oracle 9i on horsehead -// addDb( "QOCI8", "//horsehead.qt-project.org:1521/ustest.troll.no", "scott", "tiger", "" ); // Oracle 9i on horsehead -// addDb( "QOCI8", "//iceblink.qt-project.org:1521/ice.troll.no", "scott", "tiger", "" ); // Oracle 8 on iceblink (not currently working) -// addDb( "QOCI", "//silence.qt-project.org:1521/testdb", "scott", "tiger" ); // Oracle 10g on silence -// addDb( "QOCI", "//bq-oracle10g.qt-project.org:1521/XE", "scott", "tiger" ); // Oracle 10gexpress - -// This requires a local ODBC data source to be configured( pointing to a MySql database ) -// addDb( "QODBC", "mysqlodbc", "troll", "trond" ); -// addDb( "QODBC", "SqlServer", "troll", "trond" ); -// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead" ); -// addDb( "QODBC", "silencetestdb", "troll", "trond", "silence" ); -// addDb( "QODBC", "horseheadtestdb", "troll", "trondk", "horsehead" ); - -// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org" ); -// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3307 ); -// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3308, "CLIENT_COMPRESS=1" ); // MySQL 4.1.1 -// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3309, "CLIENT_COMPRESS=1" ); // MySQL 5.0.18 Linux -// addDb( "QMYSQL3", "testdb", "troll", "trond", "silence.qt-project.org" ); // MySQL 5.1.36 Windows - -// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql41.qt-project.org" ); // MySQL 4.1.22-2.el4 linux -// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql50.qt-project.org" ); // MySQL 5.0.45-7.el5 linux -// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql51.qt-project.org" ); // MySQL 5.1.36-6.7.2.i586 linux - -// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org" ); // V7.2 NOT SUPPORTED! -// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte -// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org", 5435 ); // V7.3 -// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org", 5436 ); // V7.4 -// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org", 5437 ); // V8.0.3 -// addDb( "QPSQL7", "testdb", "troll", "trond", "silence.qt-project.org" ); // V8.2.1, UTF-8 - -// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-postgres74.qt-project.org" ); // Version 7.4.19-1.el4_6.1 -// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql81.qt-project.org" ); // Version 8.1.11-1.el5_1.1 -// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql84.qt-project.org" ); // Version 8.4.1-2.1.i586 -// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql90.qt-project.org" ); // Version 9.0.0 - - -// addDb( "QDB2", "testdb", "troll", "trond", "silence.qt-project.org" ); // DB2 v9.1 on silence -// addDb( "QDB2", "testdb", "testuser", "Ee4Gabf6_", "bq-db2-972.qt-project.org" ); // DB2 - -// yes - interbase really wants the physical path on the host machine. -// addDb( "QIBASE", "/opt/interbase/qttest.gdb", "SYSDBA", "masterkey", "horsehead.qt-project.org" ); -// addDb( "QIBASE", "silence.troll.no:c:\\ibase\\testdb", "SYSDBA", "masterkey", "" ); // InterBase 7.5 on silence -// addDb( "QIBASE", "silence.troll.no:c:\\ibase\\testdb_ascii", "SYSDBA", "masterkey", "" ); // InterBase 7.5 on silence -// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird1-nokia.trolltech.com.au" ); // Firebird 1.5.5 -// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1 - -// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird1.qt-project.org" ); // Firebird 1.5.5 -// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird2.qt-project.org" ); // Firebird 2.1.1 - -// use in-memory database to prevent local files -// addDb("QSQLITE", ":memory:"); + // Test databases can be defined in a file using the following format: + // + // { + // "entries": [ + // { + // "driver": "QPSQL", + // "name": "testdb", + // "username": "postgres", + // "password": "password", + // "hostname": "localhost", + // "port": 5432, + // "parameters": "extraoptions" + // }, + // { + // .... + // } + // ] + // } + + bool added = false; + const QString databasesFile(qgetenv("QT_TEST_DATABASES_FILE")); + QFile f(databasesFile.isEmpty() ? "testdbs.json" : databasesFile); + if (f.exists() && f.open(QIODevice::ReadOnly)) { + const QJsonDocument doc = QJsonDocument::fromJson(f.readAll()); + f.close(); + const QJsonValue entriesV = doc.object().value(QLatin1String("entries")); + if (!entriesV.isArray()) { + qWarning() << "No entries in " + f.fileName(); + } else { + const QJsonArray entriesA = entriesV.toArray(); + QJsonArray::const_iterator it = entriesA.constBegin(); + while (it != entriesA.constEnd()) { + if ((*it).isObject()) { + const QJsonObject object = (*it).toObject(); + addDb(object.value(QStringLiteral("driver")).toString(), + object.value(QStringLiteral("name")).toString(), + object.value(QStringLiteral("username")).toString(), + object.value(QStringLiteral("password")).toString(), + object.value(QStringLiteral("hostname")).toString(), + object.value(QStringLiteral("port")).toInt(), + object.value(QStringLiteral("parameters")).toString()); + added = true; + } + ++it; + } + } + } QTemporaryDir *sqLiteDir = dbDir(); - if (!sqLiteDir) - return false; - addDb( QStringLiteral("QSQLITE"), QDir::toNativeSeparators(sqLiteDir->path() + QStringLiteral("/foo.db")) ); -// addDb( "QSQLITE2", QDir::toNativeSeparators(dbDir.path() + "/foo2.db") ); -// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.qt-project.org\\ICEBLINK", "troll", "trond", "" ); -// addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.qt-project.org\\SQLEXPRESS", "troll", "trond", "" ); - -// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql50.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql51.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.qt-project.org;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.qt-project.org;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.qt-project.org;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.qt-project.org;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" ); -// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" ); -// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" ); -// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2003-x86-01.qt-project.org;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2008-x86-01.qt-project.org;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC", "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\\dbs\\access\\testdb.mdb", "", "", "" ); -// addDb( "QODBC", "DRIVER={Postgresql};SERVER=bq-pgsql84.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); - return true; + if (sqLiteDir) { + addDb(QStringLiteral("QSQLITE"), QDir::toNativeSeparators(sqLiteDir->path() + QStringLiteral("/foo.db"))); + added = true; + } + return added; } // 'false' return indicates a system error, for example failure to create a temporary directory. diff --git a/tests/manual/diaglib/eventfilter.cpp b/tests/manual/diaglib/eventfilter.cpp index 3874adbdeb..0646964b4a 100644 --- a/tests/manual/diaglib/eventfilter.cpp +++ b/tests/manual/diaglib/eventfilter.cpp @@ -195,6 +195,19 @@ static void formatApplicationState(QDebug debug) #endif // HAVE_GUI_APPLICATION } +#ifdef HAVE_APPLICATION +static void formatMouseState(QObject *o, QDebug debug) +{ + if (o->isWidgetType()) { + const QWidget *w = static_cast<const QWidget *>(o); + if (QWidget::mouseGrabber() == w) + debug << " [grabbed]"; + if (w->hasMouseTracking()) + debug << " [tracking]"; + } +} +#endif // HAVE_APPLICATION + bool EventFilter::eventFilter(QObject *o, QEvent *e) { static int n = 0; @@ -210,6 +223,22 @@ bool EventFilter::eventFilter(QObject *o, QEvent *e) case QEvent::FocusIn: formatApplicationState(debug); break; +#ifdef HAVE_APPLICATION + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + case QEvent::NonClientAreaMouseButtonDblClick: + case QEvent::NonClientAreaMouseButtonPress: + case QEvent::NonClientAreaMouseButtonRelease: + case QEvent::NonClientAreaMouseMove: +# if QT_VERSION >= 0x050000 + case QEvent::Enter: +# endif + case QEvent::Leave: + formatMouseState(o, debug); + break; +#endif // HAVE_APPLICATION default: break; } diff --git a/util/edid/qedidvendortable.py b/util/edid/qedidvendortable.py index 500abf0890..bac8417326 100755 --- a/util/edid/qedidvendortable.py +++ b/util/edid/qedidvendortable.py @@ -86,10 +86,12 @@ header = """ // W A R N I N G // ------------- // -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to // version without notice, or even be removed. // +// We mean it. +// QT_BEGIN_NAMESPACE |