From 1ab3c2f14442b474a35f20f036915f52c85bdc04 Mon Sep 17 00:00:00 2001 From: ck Date: Mon, 22 Feb 2010 09:39:11 +0100 Subject: Fix compilation with namespace. --- src/gui/text/qstatictext.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h index 1e59944..00d42e0 100644 --- a/src/gui/text/qstatictext.h +++ b/src/gui/text/qstatictext.h @@ -97,10 +97,10 @@ private: friend class QStaticTextPrivate; }; -Q_DECLARE_METATYPE(QStaticText) - QT_END_NAMESPACE +Q_DECLARE_METATYPE(QStaticText) + QT_END_HEADER #endif // QSTATICTEXT_H -- cgit v0.12 From d8c496523647e075220244978f2554bd266944f6 Mon Sep 17 00:00:00 2001 From: ck Date: Mon, 22 Feb 2010 10:12:31 +0100 Subject: Fix compilation with namespace. --- src/declarative/qml/qml.h | 4 ++-- src/multimedia/base/qmediaserviceprovider.cpp | 4 +++- src/multimedia/playback/qmediaplayer.cpp | 7 ++++--- src/multimedia/qml/qsoundeffect.cpp | 2 ++ src/multimedia/qml/qsoundeffect_qsound_p.cpp | 2 ++ src/multimedia/qml/wavedecoder_p.cpp | 4 ++++ 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h index e5e7c59..a539050 100644 --- a/src/declarative/qml/qml.h +++ b/src/declarative/qml/qml.h @@ -55,8 +55,6 @@ QT_BEGIN_HEADER -QT_MODULE(Declarative) - #define QML_DECLARE_TYPE(TYPE) \ Q_DECLARE_METATYPE(TYPE *) \ Q_DECLARE_METATYPE(QList *) \ @@ -90,6 +88,8 @@ QT_END_NAMESPACE QT_BEGIN_NAMESPACE +QT_MODULE(Declarative) + #if defined(Q_OS_SYMBIAN) #define QML_DEFINE_INTERFACE(INTERFACE) \ static int defineInterface##INTERFACE = qmlRegisterInterface(#INTERFACE); diff --git a/src/multimedia/base/qmediaserviceprovider.cpp b/src/multimedia/base/qmediaserviceprovider.cpp index 8d1e0fa..eb97e16 100644 --- a/src/multimedia/base/qmediaserviceprovider.cpp +++ b/src/multimedia/base/qmediaserviceprovider.cpp @@ -48,7 +48,7 @@ #include "qmediapluginloader_p.h" #include - +QT_BEGIN_NAMESPACE class QMediaServiceProviderHintPrivate : public QSharedData { @@ -594,6 +594,8 @@ QMediaServiceProvider *QMediaServiceProvider::defaultServiceProvider() #endif } +QT_END_NAMESPACE + /*! \class QMediaServiceProviderPlugin \preliminary diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index 5f50fdb..0684bd1 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -947,9 +947,10 @@ QStringList QMediaPlayer::supportedMimeTypes(Flags flags) Such playback service can be used for beeps, ringtones, etc. */ -#include "moc_qmediaplayer.cpp" - QT_END_NAMESPACE -QT_END_NAMESPACE +QT_END_HEADER + +#include "moc_qmediaplayer.cpp" + diff --git a/src/multimedia/qml/qsoundeffect.cpp b/src/multimedia/qml/qsoundeffect.cpp index 1a67414..cee771d 100644 --- a/src/multimedia/qml/qsoundeffect.cpp +++ b/src/multimedia/qml/qsoundeffect.cpp @@ -52,6 +52,7 @@ #include "qsoundeffect_qsound_p.h" #endif +QT_BEGIN_NAMESPACE /*! \qmlclass QSoundEffect @@ -250,3 +251,4 @@ void QSoundEffect::repeat() } } +QT_END_NAMESPACE diff --git a/src/multimedia/qml/qsoundeffect_qsound_p.cpp b/src/multimedia/qml/qsoundeffect_qsound_p.cpp index 33f5bd4..0292d26 100644 --- a/src/multimedia/qml/qsoundeffect_qsound_p.cpp +++ b/src/multimedia/qml/qsoundeffect_qsound_p.cpp @@ -65,6 +65,7 @@ #include "qsoundeffect_qsound_p.h" +QT_BEGIN_NAMESPACE QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): QObject(parent), @@ -221,3 +222,4 @@ void QSoundEffectPrivate::unloadSample() m_sound = 0; } +QT_END_NAMESPACE diff --git a/src/multimedia/qml/wavedecoder_p.cpp b/src/multimedia/qml/wavedecoder_p.cpp index 5fc5a96..b7d6101 100644 --- a/src/multimedia/qml/wavedecoder_p.cpp +++ b/src/multimedia/qml/wavedecoder_p.cpp @@ -44,6 +44,8 @@ #include #include +QT_BEGIN_NAMESPACE + WaveDecoder::WaveDecoder(QIODevice *s, QObject *parent): QIODevice(parent), haveFormat(false), @@ -134,3 +136,5 @@ void WaveDecoder::handleData() emit formatKnown(); } } + +QT_END_NAMESPACE -- cgit v0.12 From 422f353135dc8a6b3694a7f0994429df7695d4bf Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 18 Feb 2010 21:45:17 +0100 Subject: remove more pointless recalculations Reviewed-by: joao --- src/corelib/tools/qlist.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index ac0dc46..1576b40 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -209,7 +209,7 @@ void **QListData::append(const QListData& l) int n = l.d->end - l.d->begin; if (n) { if (e + n > d->alloc) - realloc(grow(e + l.d->end - l.d->begin)); + realloc(grow(e + n)); ::memcpy(d->array + d->end, l.d->array + l.d->begin, n*sizeof(void*)); d->end += n; } @@ -253,11 +253,11 @@ void **QListData::insert(int i) Q_ASSERT(d->ref == 1); if (i <= 0) return prepend(); - if (i >= d->end - d->begin) + int size = d->end - d->begin; + if (i >= size) return append(); bool leftward = false; - int size = d->end - d->begin; if (d->begin == 0) { if (d->end == d->alloc) { -- cgit v0.12 From 4967231a9e5c39de3a60b61db9b6a71266a04829 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 18 Feb 2010 22:18:23 +0100 Subject: optimize queue-like structures a list to which we append after we took something from the beginning is most likely a queue, and it seems unlikely that we would suddenly start prepending to it. consequently, optimizing the prepending case by leaving the first third of the allocation free just increases the number of times the array needs to be shifted down. Reviewed-by: joao --- src/corelib/tools/qlist.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 1576b40..39c1beb 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -188,9 +188,9 @@ void **QListData::append() int n = d->end - d->begin; if (d->begin > 2 * d->alloc / 3) { // we have enough space. Just not at the end -> move it. - ::memcpy(d->array + n, d->array + d->begin, n * sizeof(void *)); - d->begin = n; - d->end = n * 2; + ::memcpy(d->array, d->array + d->begin, n * sizeof(void *)); + d->begin = 0; + d->end = n; } else { realloc(grow(d->alloc + 1)); } -- cgit v0.12 From e38f2b026a00acafab96b1fcc7c27a4446ec49d1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 18 Feb 2010 22:29:52 +0100 Subject: make queues to which only lists are appended not blow the memory append2(list) didn't use the array shifting logic the append() for single elements does. this would cause the list to grow endlessly despite leading elements being removed if only lists were ever appended. Reviewed-by: joao --- src/corelib/tools/qlist.cpp | 36 ++++++++++++++++++------------------ src/corelib/tools/qlist.h | 1 + 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 39c1beb..249b8d1 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -180,22 +180,30 @@ void QListData::realloc(int alloc) d->begin = d->end = 0; } -// ensures that enough space is available to append one element -void **QListData::append() +// ensures that enough space is available to append n elements +void **QListData::append(int n) { Q_ASSERT(d->ref == 1); - if (d->end == d->alloc) { - int n = d->end - d->begin; - if (d->begin > 2 * d->alloc / 3) { + int e = d->end; + if (e + n > d->alloc) { + int b = d->begin; + if (b - n >= 2 * d->alloc / 3) { // we have enough space. Just not at the end -> move it. - ::memcpy(d->array, d->array + d->begin, n * sizeof(void *)); + e -= b; + ::memcpy(d->array, d->array + b, e * sizeof(void *)); d->begin = 0; - d->end = n; } else { - realloc(grow(d->alloc + 1)); + realloc(grow(d->alloc + n)); } } - return d->array + d->end++; + d->end = e + n; + return d->array + e; +} + +// ensures that enough space is available to append one element +void **QListData::append() +{ + return append(1); } // ensures that enough space is available to append the list @@ -219,15 +227,7 @@ void **QListData::append(const QListData& l) // ensures that enough space is available to append the list void **QListData::append2(const QListData& l) { - Q_ASSERT(d->ref == 1); - int e = d->end; - int n = l.d->end - l.d->begin; - if (n) { - if (e + n > d->alloc) - realloc(grow(e + n)); - d->end += n; - } - return d->array + e; + return append(l.d->end - l.d->begin); } void **QListData::prepend() diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 5364e8e..fdebd7d 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -80,6 +80,7 @@ struct Q_CORE_EXPORT QListData { static Data shared_null; Data *d; void **erase(void **xi); + void **append(int n); void **append(); void **append(const QListData &l); void **append2(const QListData &l); // remove in 5.0 -- cgit v0.12 From 0eafbdd480440e413f2fd9cdf4f19354be2a0bdb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 22 Feb 2010 14:44:20 +0100 Subject: do not protect against self-assignment in QList::replace() it's not the task of the container class to do so. Reviewed-by: joao --- src/corelib/tools/qlist.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index fdebd7d..1e0cb76 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -555,12 +555,7 @@ inline void QList::replace(int i, const T &t) { Q_ASSERT_X(i >= 0 && i < p.size(), "QList::replace", "index out of range"); detach(); - if (QTypeInfo::isLarge || QTypeInfo::isStatic) { - reinterpret_cast(p.at(i))->t() = t; - } else { - const T cpy(t); - reinterpret_cast(p.at(i))->t() = cpy; - } + reinterpret_cast(p.at(i))->t() = t; } template -- cgit v0.12 From 96a3d36a33dc5c1c7e414c873316027fab6cecf9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Feb 2010 15:19:11 +0100 Subject: create temporaries more intelligently we already know that we are dealing with a movable type, so it is safe to keep a temporary copy of the raw data instead of going through the copy c'tor. this way we save a pretty useless ref()/deref() pair for each and every insertion of an implicitly shared type into a QList. the QtPodForSize class is somewhat ugly. we should use QIntegerForSize, but that's not possible without having separate template specializations, which is not possible without some bigger changes to the qt type info system. it will be beautified in due time. :) Reviewed-by: joao --- src/corelib/tools/qlist.h | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 1e0cb76..b79011e 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -96,6 +96,25 @@ struct Q_CORE_EXPORT QListData { inline void **end() const { return d->array + d->end; } }; +////////////////////////////////////////////////////////////////////////////////// +// +// QtPodForSize and QtPodForType are internal and may change or go away any time. +// We mean it. +// +////////////////////////////////////////////////////////////////////////////////// +template struct QtPodForSize { + // This base type is rather obviously broken and cannot be made + // working due to alignment constraints. + // This doesn't matter as far as QList is concerned, as we are + // using this type only for QTypeInfo::isLarge == false. + typedef struct { } Type; +}; +template <> struct QtPodForSize<1> { typedef quint8 Type; }; +template <> struct QtPodForSize<2> { typedef quint16 Type; }; +template <> struct QtPodForSize<4> { typedef quint32 Type; }; +template <> struct QtPodForSize<8> { typedef quint64 Type; }; +template struct QtPodForType : QtPodForSize { }; + template class QList { @@ -491,10 +510,11 @@ Q_OUTOFLINE_TEMPLATE void QList::append(const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); Node *n = reinterpret_cast(p.append()); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast(&cpy)); } QT_CATCH(...) { --d->end; QT_RETHROW; @@ -515,10 +535,11 @@ inline void QList::prepend(const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); Node *n = reinterpret_cast(p.prepend()); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast(&cpy)); } QT_CATCH(...) { ++d->begin; QT_RETHROW; @@ -539,10 +560,11 @@ inline void QList::insert(int i, const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); Node *n = reinterpret_cast(p.insert(i)); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast(&cpy)); } QT_CATCH(...) { p.remove(i); QT_RETHROW; -- cgit v0.12 From 9f08d620588752a6617d0e265c6b7137704e39c5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Feb 2010 21:02:23 +0100 Subject: avoid double reallocations in inserting operations operator+=() and co. would first detach, and then realloc if they found the reservation too small. in particular, appending anything to an empty list would trigger this double reallocation (first copy shared_null, then grow the copy). entirely rewritten take 3, this time without memory corruption or exhaustion ... :) Reviewed-by: joao --- src/corelib/tools/qlist.cpp | 47 ++++++++++++++++ src/corelib/tools/qlist.h | 131 ++++++++++++++++++++++++++++++++------------ 2 files changed, 143 insertions(+), 35 deletions(-) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 249b8d1..6f5bb9b 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -66,6 +66,53 @@ static int grow(int size) return x; } +/*! + * Detaches the QListData by allocating new memory for a list which will be bigger + * than the copied one and is expected to grow further. + * *idx is the desired insertion point and is clamped to the actual size of the list. + * num is the number of new elements to insert at the insertion point. + * Returns the old (shared) data, it is up to the caller to deref() and free(). + * For the new data node_copy needs to be called. + * + * \internal + */ +QListData::Data *QListData::detach_grow(int *idx, int num) +{ + Data *x = d; + int l = x->end - x->begin; + int nl = l + num; + int alloc = grow(nl); + Data* t = static_cast(qMalloc(DataHeaderSize + alloc * sizeof(void *))); + Q_CHECK_PTR(t); + + t->ref = 1; + t->sharable = true; + t->alloc = alloc; + // The space reservation algorithm's optimization is biased towards appending: + // Something which looks like an append will put the data at the beginning, + // while something which looks like a prepend will put it in the middle + // instead of at the end. That's based on the assumption that prepending + // is uncommon and even an initial prepend will eventually be followed by + // at least some appends. + int bg; + if (*idx < 0) { + *idx = 0; + bg = (alloc - nl) >> 1; + } else if (*idx > l) { + *idx = l; + bg = 0; + } else if (*idx < (l >> 1)) { + bg = (alloc - nl) >> 1; + } else { + bg = 0; + } + t->begin = bg; + t->end = bg + nl; + d = t; + + return x; +} + #if QT_VERSION >= 0x050000 # error "Remove QListData::detach(), it is only required for binary compatibility for 4.0.x to 4.2.x" #endif diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index b79011e..3a29e13 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -52,6 +52,7 @@ #endif #include +#include #include QT_BEGIN_HEADER @@ -73,6 +74,7 @@ struct Q_CORE_EXPORT QListData { enum { DataHeaderSize = sizeof(Data) - sizeof(void *) }; Data *detach(int alloc); + Data *detach_grow(int *i, int n); Data *detach(); // remove in 5.0 Data *detach2(); // remove in 5.0 Data *detach3(); // remove in 5.0 @@ -353,6 +355,7 @@ public: #endif private: + Node *detach_helper_grow(int i, int n); void detach_helper(int alloc); void detach_helper(); void free(QListData::Data *d); @@ -500,9 +503,8 @@ Q_OUTOFLINE_TEMPLATE void QList::reserve(int alloc) template Q_OUTOFLINE_TEMPLATE void QList::append(const T &t) { - detach(); - if (QTypeInfo::isLarge || QTypeInfo::isStatic) { - Node *n = reinterpret_cast(p.append()); + if (d->ref != 1) { + Node *n = detach_helper_grow(INT_MAX, 1); QT_TRY { node_construct(n, t); } QT_CATCH(...) { @@ -510,14 +512,24 @@ Q_OUTOFLINE_TEMPLATE void QList::append(const T &t) QT_RETHROW; } } else { - typedef typename QtPodForType::Type PodNode; - PodNode cpy = *reinterpret_cast(&t); - Node *n = reinterpret_cast(p.append()); - QT_TRY { - node_construct(n, *reinterpret_cast(&cpy)); - } QT_CATCH(...) { - --d->end; - QT_RETHROW; + if (QTypeInfo::isLarge || QTypeInfo::isStatic) { + Node *n = reinterpret_cast(p.append()); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + --d->end; + QT_RETHROW; + } + } else { + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); + Node *n = reinterpret_cast(p.append()); + QT_TRY { + node_construct(n, *reinterpret_cast(&cpy)); + } QT_CATCH(...) { + --d->end; + QT_RETHROW; + } } } } @@ -525,9 +537,8 @@ Q_OUTOFLINE_TEMPLATE void QList::append(const T &t) template inline void QList::prepend(const T &t) { - detach(); - if (QTypeInfo::isLarge || QTypeInfo::isStatic) { - Node *n = reinterpret_cast(p.prepend()); + if (d->ref != 1) { + Node *n = detach_helper_grow(0, 1); QT_TRY { node_construct(n, t); } QT_CATCH(...) { @@ -535,14 +546,24 @@ inline void QList::prepend(const T &t) QT_RETHROW; } } else { - typedef typename QtPodForType::Type PodNode; - PodNode cpy = *reinterpret_cast(&t); - Node *n = reinterpret_cast(p.prepend()); - QT_TRY { - node_construct(n, *reinterpret_cast(&cpy)); - } QT_CATCH(...) { - ++d->begin; - QT_RETHROW; + if (QTypeInfo::isLarge || QTypeInfo::isStatic) { + Node *n = reinterpret_cast(p.prepend()); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + ++d->begin; + QT_RETHROW; + } + } else { + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); + Node *n = reinterpret_cast(p.prepend()); + QT_TRY { + node_construct(n, *reinterpret_cast(&cpy)); + } QT_CATCH(...) { + ++d->begin; + QT_RETHROW; + } } } } @@ -550,9 +571,8 @@ inline void QList::prepend(const T &t) template inline void QList::insert(int i, const T &t) { - detach(); - if (QTypeInfo::isLarge || QTypeInfo::isStatic) { - Node *n = reinterpret_cast(p.insert(i)); + if (d->ref != 1) { + Node *n = detach_helper_grow(i, 1); QT_TRY { node_construct(n, t); } QT_CATCH(...) { @@ -560,14 +580,24 @@ inline void QList::insert(int i, const T &t) QT_RETHROW; } } else { - typedef typename QtPodForType::Type PodNode; - PodNode cpy = *reinterpret_cast(&t); - Node *n = reinterpret_cast(p.insert(i)); - QT_TRY { - node_construct(n, *reinterpret_cast(&cpy)); - } QT_CATCH(...) { - p.remove(i); - QT_RETHROW; + if (QTypeInfo::isLarge || QTypeInfo::isStatic) { + Node *n = reinterpret_cast(p.insert(i)); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + p.remove(i); + QT_RETHROW; + } + } else { + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); + Node *n = reinterpret_cast(p.insert(i)); + QT_TRY { + node_construct(n, *reinterpret_cast(&cpy)); + } QT_CATCH(...) { + p.remove(i); + QT_RETHROW; + } } } } @@ -640,6 +670,36 @@ Q_OUTOFLINE_TEMPLATE T QList::value(int i, const T& defaultValue) const } template +Q_OUTOFLINE_TEMPLATE typename QList::Node *QList::detach_helper_grow(int i, int c) +{ + Node *n = reinterpret_cast(p.begin()); + QListData::Data *x = p.detach_grow(&i, c); + QT_TRY { + node_copy(reinterpret_cast(p.begin()), + reinterpret_cast(p.begin() + i), n); + } QT_CATCH(...) { + qFree(d); + d = x; + QT_RETHROW; + } + QT_TRY { + node_copy(reinterpret_cast(p.begin() + i + c), + reinterpret_cast(p.end()), n + i); + } QT_CATCH(...) { + node_destruct(reinterpret_cast(p.begin()), + reinterpret_cast(p.begin() + i)); + qFree(d); + d = x; + QT_RETHROW; + } + + if (!x->ref.deref()) + free(x); + + return reinterpret_cast(p.begin() + i); +} + +template Q_OUTOFLINE_TEMPLATE void QList::detach_helper(int alloc) { Node *n = reinterpret_cast(p.begin()); @@ -748,8 +808,9 @@ Q_OUTOFLINE_TEMPLATE typename QList::iterator QList::erase(typename QList< template Q_OUTOFLINE_TEMPLATE QList &QList::operator+=(const QList &l) { - detach(); - Node *n = reinterpret_cast(p.append2(l.p)); + Node *n = (d->ref != 1) + ? detach_helper_grow(INT_MAX, l.size()) + : reinterpret_cast(p.append2(l.p)); QT_TRY{ node_copy(n, reinterpret_cast(p.end()), reinterpret_cast(l.p.begin())); } QT_CATCH(...) { -- cgit v0.12 From 57cc5c50df4fc3673c948e8a55b4bab991e9cb7f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 22 Feb 2010 15:39:17 +0100 Subject: clean up x11 desktop detection KDE_FULL_SESSION is reliable since kde 2.x or so. DESKTOP_SESSION is not reliable, unless one uses a new gnome. GNOME_DESKTOP_SESSION_ID was temporarily unreliable. the two together should be reliable. copy the xfce4 detection from the xdg-open tool. assumed to be reliable. remove the window manager hacks, as they are redundand with the asssumedly reliable detection methods above. Reviewed-by: jbache --- src/gui/kernel/qapplication_x11.cpp | 116 ++++++++++-------------------------- src/gui/kernel/qt_x11_p.h | 5 +- 2 files changed, 31 insertions(+), 90 deletions(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 34865b5..c6e192b 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -208,11 +208,8 @@ static const char * x11_atomnames = { "_MOTIF_WM_HINTS\0" "DTWM_IS_RUNNING\0" - "KDE_FULL_SESSION\0" - "KWIN_RUNNING\0" - "KWM_RUNNING\0" - "GNOME_BACKGROUND_PROPERTIES\0" "ENLIGHTENMENT_DESKTOP\0" + "_DT_SAVE_MODE\0" "_SGI_DESKS_MANAGER\0" // EWMH (aka NETWM) @@ -626,8 +623,6 @@ static int qt_x_errhandler(Display *dpy, XErrorEvent *err) || err->resourceid == XA_RGB_DEFAULT_MAP || err->resourceid == ATOM(_NET_SUPPORTED) || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK) - || err->resourceid == ATOM(KDE_FULL_SESSION) - || err->resourceid == ATOM(KWIN_RUNNING) || err->resourceid == ATOM(XdndProxy) || err->resourceid == ATOM(XdndAware))) { // Perhaps we're running under SECURITY reduction? :/ @@ -2222,87 +2217,36 @@ void qt_init(QApplicationPrivate *priv, int, X11->desktopEnvironment = DE_UNKNOWN; X11->desktopVersion = 0; - // See if the current window manager is using the freedesktop.org spec to give its name - Window windowManagerWindow = XNone; - Atom typeReturned; - int formatReturned; - unsigned long nitemsReturned; - unsigned long unused; - unsigned char *data = 0; - if (XGetWindowProperty(QX11Info::display(), QX11Info::appRootWindow(), - ATOM(_NET_SUPPORTING_WM_CHECK), - 0, 1024, False, XA_WINDOW, &typeReturned, - &formatReturned, &nitemsReturned, &unused, &data) - == Success) { - if (typeReturned == XA_WINDOW && formatReturned == 32) - windowManagerWindow = *((Window*) data); - if (data) - XFree(data); - - if (windowManagerWindow != XNone) { - QString wmName; - Atom utf8atom = ATOM(UTF8_STRING); - if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME), - 0, 1024, False, utf8atom, &typeReturned, - &formatReturned, &nitemsReturned, &unused, &data) - == Success) { - if (typeReturned == utf8atom && formatReturned == 8) - wmName = QString::fromUtf8((const char*)data); - if (data) - XFree(data); - if (wmName == QLatin1String("KWin")) - X11->desktopEnvironment = DE_KDE; - if (wmName == QLatin1String("Metacity")) - X11->desktopEnvironment = DE_GNOME; - } - } - } - - // Running a different/newer/older window manager? Try some other things - if (X11->desktopEnvironment == DE_UNKNOWN){ - Atom type; - int format; - unsigned long length, after; - uchar *data = 0; - - QString session = QString::fromLocal8Bit(qgetenv("DESKTOP_SESSION")); - if (session == QLatin1String("kde")) { - X11->desktopEnvironment = DE_KDE; - } else if (session == QLatin1String("gnome") || session == QLatin1String("xfce")) { - X11->desktopEnvironment = DE_GNOME; - } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING), - 0, 1, False, AnyPropertyType, &type, &format, &length, - &after, &data) == Success && length) { - // DTWM is running, meaning most likely CDE is running... - X11->desktopEnvironment = DE_CDE; - } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), - ATOM(GNOME_BACKGROUND_PROPERTIES), 0, 1, False, AnyPropertyType, - &type, &format, &length, &after, &data) == Success && length) { - X11->desktopEnvironment = DE_GNOME; - } else if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) { - X11->desktopEnvironment = DE_GNOME; - } else if ((XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KDE_FULL_SESSION), - 0, 1, False, AnyPropertyType, &type, &format, &length, &after, &data) == Success - && length) - || (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KWIN_RUNNING), - 0, 1, False, AnyPropertyType, &type, &format, &length, - &after, &data) == Success - && length) - || (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KWM_RUNNING), - 0, 1, False, AnyPropertyType, &type, &format, &length, - &after, &data) == Success && length)) { - X11->desktopEnvironment = DE_KDE; - } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_SGI_DESKS_MANAGER), - 0, 1, False, XA_WINDOW, &type, &format, &length, &after, &data) == Success - && length) { - X11->desktopEnvironment = DE_4DWM; - } - if (data) - XFree((char *)data); + Atom type; + int format; + unsigned long length, after; + uchar *data = 0; + + if (!qgetenv("KDE_FULL_SESSION").isEmpty()) { + X11->desktopEnvironment = DE_KDE; + X11->desktopVersion = qgetenv("KDE_SESSION_VERSION").toInt(); + } else if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty() // Deprecated for some reason. + || qgetenv("DESKTOP_SESSION") == "gnome") { // De-facto-standardized by GNOME. + X11->desktopEnvironment = DE_GNOME; + } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE), + 0, 2, False, XA_STRING, &type, &format, &length, + &after, &data) == Success + && !strcmp(reinterpret_cast(data), "xfce4")) { + // Pretend that xfce4 is gnome, as it uses the same libraries. + // The detection above is stolen from xdg-open. + X11->desktopEnvironment = DE_GNOME; + } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING), + 0, 1, False, AnyPropertyType, &type, &format, &length, + &after, &data) == Success && length) { + // DTWM is running, meaning most likely CDE is running... + X11->desktopEnvironment = DE_CDE; + } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_SGI_DESKS_MANAGER), + 0, 1, False, XA_WINDOW, &type, &format, &length, &after, &data) == Success + && length) { + X11->desktopEnvironment = DE_4DWM; } - - if (X11->desktopEnvironment == DE_KDE) - X11->desktopVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); + if (data) + XFree((char *)data); #if !defined(QT_NO_STYLE_GTK) if (X11->desktopEnvironment == DE_GNOME) { diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index b2ce754..167557b 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -564,11 +564,8 @@ struct QX11Data _MOTIF_WM_HINTS, DTWM_IS_RUNNING, - KDE_FULL_SESSION, - KWIN_RUNNING, - KWM_RUNNING, - GNOME_BACKGROUND_PROPERTIES, ENLIGHTENMENT_DESKTOP, + _DT_SAVE_MODE, _SGI_DESKS_MANAGER, // EWMH (aka NETWM) -- cgit v0.12