From 269fdbdd2bedda5f5eacb751224d3a3fc3eed5bc Mon Sep 17 00:00:00 2001 From: Urs Fleisch Date: Fri, 26 Feb 2016 17:46:09 +0100 Subject: xcb: Fix drag and drop to applications like Emacs and Chromium. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops without matching time stamp do not work. I have fixed the issue by reanimating the findXdndAwareParent() function (adapted to XCB) and using it to find a matching transaction if all else fails. Task-number: QTBUG-45812 Change-Id: Ibca15bbab02ccf2f25280418e9edf36972ebf9a0 Reviewed-by: Błażej Szczygieł Reviewed-by: Dmitry Shachnev Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbdrag.cpp | 55 +++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index f5cc87394b..f1428d0a96 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1072,6 +1072,40 @@ void QXcbDrag::cancel() send_leave(); } +// find an ancestor with XdndAware on it +static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window) +{ + xcb_window_t target = 0; + forever { + // check if window has XdndAware + xcb_get_property_cookie_t gpCookie = Q_XCB_CALL( + xcb_get_property(c->xcb_connection(), false, window, + c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); + xcb_get_property_reply_t *gpReply = xcb_get_property_reply( + c->xcb_connection(), gpCookie, 0); + bool aware = gpReply && gpReply->type != XCB_NONE; + free(gpReply); + if (aware) { + target = window; + break; + } + + // try window's parent + xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL( + xcb_query_tree_unchecked(c->xcb_connection(), window)); + xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply( + c->xcb_connection(), qtCookie, NULL); + if (!qtReply) + break; + xcb_window_t root = qtReply->root; + xcb_window_t parent = qtReply->parent; + free(qtReply); + if (window == root) + break; + window = parent; + } + return target; +} void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event) { @@ -1099,17 +1133,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event // xcb_convert_selection() that we sent the XdndDrop event to. at = findTransactionByWindow(event->requestor); } -// if (at == -1 && event->time == XCB_CURRENT_TIME) { -// // previous Qt versions always requested the data on a child of the target window -// // using CurrentTime... but it could be asking for either drop data or the current drag's data -// Window target = findXdndAwareParent(event->requestor); -// if (target) { -// if (current_target && current_target == target) -// at = -2; -// else -// at = findXdndDropTransactionByWindow(target); -// } -// } + + if (at == -1 && event->time == XCB_CURRENT_TIME) { + xcb_window_t target = findXdndAwareParent(connection(), event->requestor); + if (target) { + if (current_target == target) + at = -2; + else + at = findTransactionByWindow(target); + } + } } QDrag *transactionDrag = 0; -- cgit v1.2.3 From e2f7d04a6143d2d0dfa0d0ec588e87f32c6f2e23 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 25 Apr 2016 08:54:48 +0200 Subject: Add missing initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Coverity, CIDs: 10724, 10725. Data member _iterator is not initialized. Change-Id: I0c94f5cef031e208aab1687209282fae0317f0ab Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qmetatype.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 899a51173e..b6cfad56b5 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1183,6 +1183,7 @@ public: public: template QAssociativeIterableImpl(const T*p) : _iterable(p) + , _iterator(Q_NULLPTR) , _metaType_id_key(qMetaTypeId()) , _metaType_flags_key(QTypeInfo::isPointer) , _metaType_id_value(qMetaTypeId()) @@ -1202,6 +1203,7 @@ public: QAssociativeIterableImpl() : _iterable(Q_NULLPTR) + , _iterator(Q_NULLPTR) , _metaType_id_key(QMetaType::UnknownType) , _metaType_flags_key(0) , _metaType_id_value(QMetaType::UnknownType) -- cgit v1.2.3 From 90631dcbf5683f54e27ecceab9b8f0a1885fdc1e Mon Sep 17 00:00:00 2001 From: Marko Kangas Date: Wed, 13 Apr 2016 15:19:53 +0300 Subject: Change scroll and text areas to respect native wheel focus rule [ChangeLog][QtWidgets][QAbstractScrollArea,QTextEdit,QPlainTextEdit] Changed focus to Qt::StrongFocus. That respects platforms' native guidelines. Task-number: QTBUG-52559 Change-Id: I2aa25d25bbc15facce85ceb7d4a4c1d0ac7df962 Reviewed-by: Marc Mutz --- src/widgets/widgets/qabstractscrollarea.cpp | 2 +- src/widgets/widgets/qplaintextedit.cpp | 2 +- src/widgets/widgets/qtextedit.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 65d06eafc5..2e2a042bf1 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -303,7 +303,7 @@ void QAbstractScrollAreaPrivate::init() viewportFilter.reset(new QAbstractScrollAreaFilter(this)); viewport->installEventFilter(viewportFilter.data()); viewport->setFocusProxy(q); - q->setFocusPolicy(Qt::WheelFocus); + q->setFocusPolicy(Qt::StrongFocus); q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 8a64e3a397..59ece406cc 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -795,7 +795,7 @@ void QPlainTextEditPrivate::init(const QString &txt) viewport->setBackgroundRole(QPalette::Base); q->setAcceptDrops(true); - q->setFocusPolicy(Qt::WheelFocus); + q->setFocusPolicy(Qt::StrongFocus); q->setAttribute(Qt::WA_KeyCompression); q->setAttribute(Qt::WA_InputMethodEnabled); q->setInputMethodHints(Qt::ImhMultiLine); diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp index c4503538c6..28666f76ce 100644 --- a/src/widgets/widgets/qtextedit.cpp +++ b/src/widgets/widgets/qtextedit.cpp @@ -171,7 +171,7 @@ void QTextEditPrivate::init(const QString &html) viewport->setBackgroundRole(QPalette::Base); q->setAcceptDrops(true); - q->setFocusPolicy(Qt::WheelFocus); + q->setFocusPolicy(Qt::StrongFocus); q->setAttribute(Qt::WA_KeyCompression); q->setAttribute(Qt::WA_InputMethodEnabled); q->setInputMethodHints(Qt::ImhMultiLine); -- cgit v1.2.3 From 0b35167c209481cfe6450c78b5dfb490280c428f Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 26 Apr 2016 10:56:53 +0200 Subject: QZipReader - test that QFile::open was, indeed, successful. Coverity, CIDs 10917, 10918. This fix looks like purely cosmetic and unneeded: we check f->error() after f->open(). Unfortunately, f->open() can fail without setting an error (if you provided an invalid mode). Change-Id: Idbfcb9305b3f004e5e425cb6076b41e193b8d473 Reviewed-by: Konstantin Ritt --- src/gui/text/qzip.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index 31ef8f87be..a3112cc7fb 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -816,9 +816,8 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode) { QScopedPointer f(new QFile(archive)); - f->open(mode); QZipReader::Status status; - if (f->error() == QFile::NoError) + if (f->open(mode) && f->error() == QFile::NoError) status = NoError; else { if (f->error() == QFile::ReadError) @@ -1112,9 +1111,8 @@ void QZipReader::close() QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode) { QScopedPointer f(new QFile(fileName)); - f->open(mode); QZipWriter::Status status; - if (f->error() == QFile::NoError) + if (f->open(mode) && f->error() == QFile::NoError) status = QZipWriter::NoError; else { if (f->error() == QFile::WriteError) -- cgit v1.2.3 From 685dcd8527215bb0deb239964fa8ea35bd676203 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 25 Apr 2016 13:29:13 +0200 Subject: OSX: mark mouse events from tablet devices as synthesized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is equivalent to d7db6c6c1944894737babf3958d0cff1e6222a22 on the xcb platform. Task-number: QTBUG-51617 Change-Id: I837a764c8382244307ba6aa02bd8bde12bd08bff Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.h | 2 +- src/plugins/platforms/cocoa/qnsview.mm | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 50b456cab7..2d4ad7aad3 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -127,7 +127,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)otherMouseUp:(NSEvent *)theEvent; - (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent; -- (void)handleTabletEvent: (NSEvent *)theEvent; +- (bool)handleTabletEvent: (NSEvent *)theEvent; - (void)tabletPoint: (NSEvent *)theEvent; - (void)tabletProximity: (NSEvent *)theEvent; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 4ac34b01ff..a2f97c78dc 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -727,7 +727,7 @@ QT_WARNING_POP - (void)handleMouseEvent:(NSEvent *)theEvent { - [self handleTabletEvent: theEvent]; + bool isTabletEvent = [self handleTabletEvent: theEvent]; QPointF qtWindowPoint; QPointF qtScreenPoint; @@ -756,7 +756,8 @@ QT_WARNING_POP nativeDrag->setLastMouseEvent(theEvent, self); Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]]; - QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers); + QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers, + isTabletEvent ? Qt::MouseEventSynthesizedByQt : Qt::MouseEventNotSynthesized); } - (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent @@ -1056,11 +1057,11 @@ struct QCocoaTabletDeviceData typedef QHash QCocoaTabletDeviceDataHash; Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash) -- (void)handleTabletEvent: (NSEvent *)theEvent +- (bool)handleTabletEvent: (NSEvent *)theEvent { NSEventType eventType = [theEvent type]; if (eventType != NSTabletPoint && [theEvent subtype] != NSTabletPointEventSubtype) - return; // Not a tablet event. + return false; // Not a tablet event. ulong timestamp = [theEvent timestamp] * 1000; @@ -1073,7 +1074,7 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash) // Error: Unknown tablet device. Qt also gets into this state // when running on a VM. This appears to be harmless; don't // print a warning. - return; + return false; } const QCocoaTabletDeviceData &deviceData = tabletDeviceDataHash->value(deviceId); @@ -1114,6 +1115,7 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash) deviceData.device, deviceData.pointerType, buttons, pressure, xTilt, yTilt, tangentialPressure, rotation, z, deviceData.uid, keyboardModifiers); + return true; } - (void)tabletPoint: (NSEvent *)theEvent -- cgit v1.2.3 From d7a3b6145999d015997e26e12a7345f774b053f3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 25 Apr 2016 13:29:19 +0200 Subject: Windows QPA/High DPI: Scale accessibility coordinates. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use High DPI when interfacing with the Accessibility API. Task-number: QTBUG-52943 Task-number: QTBUG-50991 Change-Id: Ica4489222dca5d58864172470e634f709deb69f8 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/windows/accessible/iaccessible2.cpp | 7 +++++-- .../platforms/windows/accessible/qwindowsmsaaaccessible.cpp | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 7c0b0370b3..7abb98f385 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -660,9 +661,11 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locationInParent(long *x, l QAccessibleInterface *parentIface = accessible->parent(); if (parentIface && parentIface->isValid()) topLeft -= parentIface->rect().topLeft(); + const QPoint nativeTopLeft = QHighDpi::toNativeLocalPosition(topLeft, accessible->window()); - *x = topLeft.x(); - *y = topLeft.y(); + + *x = nativeTopLeft.x(); + *y = nativeTopLeft.y(); return S_OK; } diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 4ecf78dbf6..5ca83fa9f2 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -49,6 +49,7 @@ #include #include #include +#include //#include #ifndef UiaRootObjectId @@ -497,7 +498,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yT if (!accessible) return E_FAIL; - QAccessibleInterface *child = accessible->childAt(xLeft, yTop); + const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), accessible->window()); + QAccessibleInterface *child = accessible->childAt(pos.x(), pos.y()); if (child == 0) { // no child found, return this item if it contains the coordinates if (accessible->rect().contains(xLeft, yTop)) { @@ -539,7 +541,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long QAccessibleInterface *acc = childPointer(accessible, varID); if (!acc || !acc->isValid()) return E_FAIL; - const QRect rect = acc->rect(); + const QRect rect = QHighDpi::toNativePixels(acc->rect(), accessible->window()); *pxLeft = rect.x(); *pyTop = rect.y(); -- cgit v1.2.3 From 31c7b24aa5f57fbe8258c9e9845c8d630af4aec1 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 1 Apr 2016 23:55:25 +0200 Subject: Silence MSVC warnings when using certain std algorithms The MSVC STL warns when passing naked pointers as non-bounded iterators to algorithms such as std::equal and std::copy, in an attempt to inform users that the range specified by that iterator has an implicit minimum size that the caller of the algorithm must ensure is met: warning C4996: 'std::_Equal1': Function call with parameters that may be unsafe - \ this call relies on the caller to check that the passed values are correct. To \ disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to \ use Visual C++ 'Checked Iterators' When building Qt, as well as when building user projects with qmake (cf. 0a76b6bc7f98900ea884cd10ccca1a332e5bdba5), we globally disable this warning (with -D_SCL_SECURE_NO_WARNINGS), but since we started using STL algorithms in public headers (e.g. in qvector.h), users get this warning in their own projects now, unless they, too, define said macro. But such a requirement is against the Qt policy to have headers that are warning-free as much as possible. The suggested way of fixing this warning is to wrap the naked pointer in a stdext::unchecked_array_iterator before passing it to the algorithm, cf. examples in https://msdn.microsoft.com/en-us/library/ttcz0bys%28v=vs.120%29.aspx or, together with the capacity-made-explicit, in a stdext::checked_array_iterator. To avoid ifdefs for platforms that don't have these extensions (which, incidentally, for the unchecked case, includes MSVC 2012), wrap the calls in macros. The end game here is to drop -D_SCL_SECURE_NO_WARNINGS, at least for public headers, even though this commit also adds the wrapper to implementation and private header files. An alternative to the wrapper would have been the version of std::equal that takes four iterators. However, that is a C++14 library feature, while this version of Qt still needs to compile with a C++98 compiler, and, more importantly, there isn't, and never will be, a corresponding 4-iterator version of std::copy. Task-number: QTBUG-47948 Done-with: Stephen Kelly Change-Id: I1bbab257fb5f1c5042939c382a412b596112ff26 Reviewed-by: Stephen Kelly --- src/corelib/global/qcompilerdetection.h | 12 ++++++++++++ src/corelib/kernel/qcoreapplication.cpp | 2 +- src/corelib/tools/qlist.h | 2 +- src/corelib/tools/qvarlengtharray.h | 7 ++++--- src/corelib/tools/qvector.h | 2 +- src/gui/kernel/qkeysequence.cpp | 2 +- src/gui/kernel/qkeysequence_p.h | 3 ++- src/plugins/platforms/windows/accessible/iaccessible2.cpp | 12 ++++++++---- src/plugins/platforms/windows/array.h | 3 ++- src/plugins/platforms/windows/qwindowsinputcontext.cpp | 2 +- 10 files changed, 33 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index b11237dce5..25043dab75 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -94,6 +94,12 @@ # define Q_DECL_DEPRECATED_X(text) __declspec(deprecated(text)) # define Q_DECL_EXPORT __declspec(dllexport) # define Q_DECL_IMPORT __declspec(dllimport) +# if _MSC_VER >= 1800 +# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) stdext::make_unchecked_array_iterator(x) +# endif +# if _MSC_VER >= 1500 +# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N)) +# endif /* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ # if defined(__INTEL_COMPILER) # define Q_DECL_VARIABLE_DEPRECATED @@ -1117,6 +1123,12 @@ #ifndef Q_DECL_CONST_FUNCTION # define Q_DECL_CONST_FUNCTION Q_DECL_PURE_FUNCTION #endif +#ifndef QT_MAKE_UNCHECKED_ARRAY_ITERATOR +# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) (x) +#endif +#ifndef QT_MAKE_CHECKED_ARRAY_ITERATOR +# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) (x) +#endif /* * Warning/diagnostic handling diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 30a3204d3d..b3b35dc9b6 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -444,7 +444,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint if (!isArgvModified(argc, argv)) { origArgc = argc; origArgv = new char *[argc]; - std::copy(argv, argv + argc, origArgv); + std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc)); } #endif // Q_OS_WIN && !Q_OS_WINRT diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 9a57a2c6a5..e04a6be1ab 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -846,7 +846,7 @@ inline bool QList::op_eq_impl(const QList &l, QListData::ArrayCompatibleLayou const T *lb = reinterpret_cast(l.p.begin()); const T *b = reinterpret_cast(p.begin()); const T *e = reinterpret_cast(p.end()); - return std::equal(b, e, lb); + return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(lb, l.p.size())); } template diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index bb15d66439..8371352061 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -96,7 +96,8 @@ public: QVarLengthArray &operator=(std::initializer_list list) { resize(list.size()); - std::copy(list.begin(), list.end(), this->begin()); + std::copy(list.begin(), list.end(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size())); return *this; } #endif @@ -467,7 +468,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray::iterator QVarLengthA int l = int(aend - ptr); int n = l - f; if (QTypeInfo::isComplex) { - std::copy(ptr + l, ptr + s, ptr + f); + std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f)); T *i = ptr + s; T *b = ptr + s - n; while (i != b) { @@ -489,7 +490,7 @@ bool operator==(const QVarLengthArray &l, const QVarLengthArray diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 3ce33fb477..691872cb36 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -767,7 +767,7 @@ bool QVector::operator==(const QVector &v) const const T *vb = v.d->begin(); const T *b = d->begin(); const T *e = d->end(); - return std::equal(b, e, vb); + return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(vb, v.d->size)); } template diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 6bb80042ee..a0818b8d20 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -1637,7 +1637,7 @@ QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence) s >> keys[i]; } qAtomicDetach(keysequence.d); - std::copy(keys, keys + MaxKeys, keysequence.d->key); + std::copy(keys, keys + MaxKeys, QT_MAKE_CHECKED_ARRAY_ITERATOR(keysequence.d->key, MaxKeys)); return s; } diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h index 6d20f798b3..9525a343dc 100644 --- a/src/gui/kernel/qkeysequence_p.h +++ b/src/gui/kernel/qkeysequence_p.h @@ -70,7 +70,8 @@ public: } inline QKeySequencePrivate(const QKeySequencePrivate ©) : ref(1) { - std::copy(copy.key, copy.key + MaxKeyCount, key); + std::copy(copy.key, copy.key + MaxKeyCount, + QT_MAKE_CHECKED_ARRAY_ITERATOR(key, MaxKeyCount)); } QAtomicInt ref; int key[MaxKeyCount]; diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 7abb98f385..5e0794bd95 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -602,7 +602,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex // The IDL documents that the client must free with CoTaskMemFree arrayOfBindingsToReturn = coTaskMemAllocArray(numBindings); std::transform(keyBindings.constBegin(), keyBindings.constEnd(), - arrayOfBindingsToReturn, QStringToBSTR); + QT_MAKE_CHECKED_ARRAY_ITERATOR(arrayOfBindingsToReturn, numBindings), + QStringToBSTR); } } *keyBindings = arrayOfBindingsToReturn; @@ -986,7 +987,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **sele *selectedColumns = Q_NULLPTR; if (count) { *selectedColumns = coTaskMemAllocArray(count); - std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedColumns); + std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedColumns, count)); } return count ? S_OK : S_FALSE; } @@ -1008,7 +1010,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selecte *selectedRows = Q_NULLPTR; if (count) { *selectedRows = coTaskMemAllocArray(count); - std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedRows); + std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedRows, count)); } return count ? S_OK : S_FALSE; } @@ -1677,7 +1680,8 @@ HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList(count); std::transform(inputCells.constBegin(), inputCells.constEnd(), - *outputAccessibles, QWindowsAccessibility::wrap); + QT_MAKE_CHECKED_ARRAY_ITERATOR(*outputAccessibles, count), + QWindowsAccessibility::wrap); } return count > 0 ? S_OK : S_FALSE; } diff --git a/src/plugins/platforms/windows/array.h b/src/plugins/platforms/windows/array.h index ea08432a29..df98d782da 100644 --- a/src/plugins/platforms/windows/array.h +++ b/src/plugins/platforms/windows/array.h @@ -79,7 +79,8 @@ public: const T *oldData = data; data = new T[capacity]; if (oldData) { - std::copy(oldData, oldData + m_size, data); + std::copy(oldData, oldData + m_size, + QT_MAKE_CHECKED_ARRAY_ITERATOR(data, capacity)); delete [] oldData; } m_capacity = capacity; diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 1faa00d095..4d4be3d858 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -650,7 +650,7 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv) reconv->dwTargetStrOffset = reconv->dwCompStrOffset; ushort *pastReconv = reinterpret_cast(reconv + 1); std::copy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(), - pastReconv); + QT_MAKE_UNCHECKED_ARRAY_ITERATOR(pastReconv)); return memSize; } -- cgit v1.2.3 From a1e3a0daed6c056c3b957151605f0f277fd38d3c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 25 Mar 2016 10:40:44 +0100 Subject: QString: Fix UBs (signed overflow) in hashed string search Similar change to 390ea21873cf229447c2dcaea85a40e472fab03c, but more extensive because the hash variables were not, yet, of unsigned type. This brings the three hashed string search algorithms in QtBase (in QString, QByteArray and QByteArrayMatcher) in line again. Found by UBSan, fixing the following bunch of errors: tools/qstring.cpp:3080:38: runtime error: left shift of negative value -1291179264 tools/qstring.cpp:3081:42: runtime error: left shift of negative value -1291179264 tools/qstring.cpp:3091:13: runtime error: left shift of 73 by 26 places cannot be represented in type 'int' tools/qstring.cpp:3091:13: runtime error: left shift of negative value -1255957171 tools/qstring.cpp:3091:13: runtime error: signed integer overflow: 1783052986 - -1207959552 cannot be represented in type 'int' tools/qstring.cpp:3097:37: runtime error: left shift of negative value -1298753576 tools/qstring.cpp:3098:41: runtime error: left shift of negative value -1298753576 tools/qstring.cpp:3107:13: runtime error: left shift of negative value -1508912760 tools/qstring.cpp:3158:38: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3159:42: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3169:13: runtime error: left shift of negative value -1657715810 tools/qstring.cpp:3173:38: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3174:42: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3183:13: runtime error: left shift of negative value -1657715810 Change-Id: I1436eb61369919df9fe34251f863dd54fb58af98 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qstring.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 983d1213d9..6bbaf05fef 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -705,8 +705,8 @@ static int findChar(const QChar *str, int len, QChar ch, int from, } #define REHASH(a) \ - if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \ - hashHaystack -= (a) << sl_minus_1; \ + if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \ + hashHaystack -= uint(a) << sl_minus_1; \ hashHaystack <<= 1 inline bool qIsUpper(char ch) @@ -3072,8 +3072,9 @@ int qFindString( const ushort *needle = (const ushort *)needle0; const ushort *haystack = (const ushort *)haystack0 + from; const ushort *end = (const ushort *)haystack0 + (l-sl); - const int sl_minus_1 = sl-1; - int hashNeedle = 0, hashHaystack = 0, idx; + const uint sl_minus_1 = sl - 1; + uint hashNeedle = 0, hashHaystack = 0; + int idx; if (cs == Qt::CaseSensitive) { for (idx = 0; idx < sl; ++idx) { @@ -3148,10 +3149,11 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee const ushort *end = haystack; haystack += from; - const int sl_minus_1 = sl-1; + const uint sl_minus_1 = sl - 1; const ushort *n = needle+sl_minus_1; const ushort *h = haystack+sl_minus_1; - int hashNeedle = 0, hashHaystack = 0, idx; + uint hashNeedle = 0, hashHaystack = 0; + int idx; if (cs == Qt::CaseSensitive) { for (idx = 0; idx < sl; ++idx) { -- cgit v1.2.3 From 7565b4ec9565cb8e52c113c693a0865da86eaeed Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 23 Apr 2016 00:02:24 +0200 Subject: QSslSocket: remove unused variable in q_X509Callback() It's been unused ever since it was added in bba86a01c9828d03b1564984a08561d62686d329. Change-Id: I6d5bc27a0744d37f873245c92a4e6ba8fc90c062 Reviewed-by: Lars Knoll --- src/network/ssl/qsslsocket_openssl.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 8caa56ee5b..9df0c693ab 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -277,7 +277,6 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx) qCDebug(lcSsl) << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem(); qCDebug(lcSsl) << "dumping chain"; foreach (QSslCertificate cert, QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(q_X509_STORE_CTX_get_chain(ctx))) { - QString certFormat(QStringLiteral("O=%1 CN=%2 L=%3 OU=%4 C=%5 ST=%6")); qCDebug(lcSsl) << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization) << "CN=" << cert.issuerInfo(QSslCertificate::CommonName) << "L=" << cert.issuerInfo(QSslCertificate::LocalityName) -- cgit v1.2.3 From 2e9fc0d3f06c41f0a3d6c68d321ea56a761b25bf Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 26 Apr 2016 09:31:39 +0200 Subject: testlib: added env QTEST_FUNCTION_TIMEOUT for single test function timeout This is a regression with 5.5, it causes some customer test functions crash. d3d10cf2 introduced the 5 minutes timeout. The timeout could be changed after this. Task-number: QTBUG-52402 Change-Id: I8940bbde5004b4d888732b551274f079ddf20563 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Friedemann Kleint --- src/testlib/qtestcase.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 4643013371..6e30a5d429 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1455,6 +1455,7 @@ namespace QTest static int keyDelay = -1; static int mouseDelay = -1; static int eventDelay = -1; + static int timeout = -1; static bool noCrashHandler = false; /*! \internal @@ -1506,6 +1507,18 @@ int Q_TESTLIB_EXPORT defaultKeyDelay() return keyDelay; } +static int defaultTimeout() +{ + if (timeout == -1) { + bool ok = false; + timeout = qEnvironmentVariableIntValue("QTEST_FUNCTION_TIMEOUT", &ok); + + if (!ok || timeout <= 0) + timeout = 5*60*1000; + } + return timeout; +} + static bool isValidSlot(const QMetaMethod &sl) { if (sl.access() != QMetaMethod::Private || sl.parameterCount() != 0 @@ -2119,7 +2132,7 @@ public: void beginTest() { QMutexLocker locker(&mutex); - timeout.store(5*60*1000); + timeout.store(defaultTimeout()); waitCondition.wakeAll(); } -- cgit v1.2.3 From 6844f60dae50dcbec9b016531c21a904fe965b9c Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 22 Apr 2016 11:52:29 -0700 Subject: QCocoaMenu: Have the menu delegate return the right amount of items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases we move menu items around, therefore we should not rely on QCocoaMenu::items() being the actual items inside the menu. But, since the NSMenu is updated before hand, we can rely on NSMenu.numberOfItems instead. Change-Id: Icd4497beca4f52a6d38408eeaa2e6ec71b579685 Task-number: QTBUG-52931 Reviewed-by: Timur Pocheptsov Reviewed-by: Eike Ziller Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 6ed7aa0e06..878c96d33a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -99,7 +99,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); - (NSInteger)numberOfItemsInMenu:(NSMenu *)menu { Q_ASSERT(m_menu->nsMenu() == menu); - return m_menu->items().count(); + return menu.numberOfItems; } - (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel -- cgit v1.2.3 From 5795c86e8b84d9026c2c768e816d2aea620a7ec7 Mon Sep 17 00:00:00 2001 From: Palo Kisa Date: Tue, 26 Apr 2016 08:55:56 +0200 Subject: QFileDialog: Fix single-click activation In QFileDialogPrivate::_q_enterDirectory() the QStyle::styleHint() for QStyle::SH_ItemView_ActivateItemOnSingleClick was called w/o the widget. By such usage the possible StyleSheet setting was ignored, e.g. "QAbstractItemView { activate-on-singleclick: 1; }". Task-number: QTBUG-50871 Change-Id: I7a32c4841db7113f32c3823581c2becc1677e3cc Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qfiledialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 3f3a6e7c65..7d34b6de4a 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -3594,7 +3594,7 @@ void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index) } } else { // Do not accept when shift-clicking to multi-select a file in environments with single-click-activation (KDE) - if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) + if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, Q_NULLPTR, qFileDialogUi->treeView) || q->fileMode() != QFileDialog::ExistingFiles || !(QGuiApplication::keyboardModifiers() & Qt::CTRL)) { q->accept(); } -- cgit v1.2.3 From 6493bcaf3ca4d233be4f3bfd8d16d860f47e8aa7 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 27 Apr 2016 15:09:55 +0400 Subject: Check for required capability only when FC_CAPABILITY is available If, by some reason, querying FC_CAPABILITY has failed, believe FC_LANG unconditionally. Change-Id: Idf94150359dff555f2a50ccaf146722407f43477 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 5305b8b970..fc04f3ab79 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -441,7 +441,7 @@ static void populateFromPattern(FcPattern *pattern) && requiresOpenType(j) && openType[j]) { FcChar8 *cap; res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap); - if (res != FcResultMatch || !strstr((const char *)cap, openType[j])) + if (res == FcResultMatch && strstr(reinterpret_cast(cap), openType[j]) == 0) writingSystems.setSupported(QFontDatabase::WritingSystem(j),false); } } -- cgit v1.2.3 From 75bd795c9f6e5b970168605c9d6c41e60b28179a Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 27 Apr 2016 15:16:39 +0400 Subject: Query FC_CAPABILITY once per pattern Change-Id: I5f1219d5a476f1bd09e8c01847fe886f342b28a0 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index fc04f3ab79..c15e0a1183 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -436,11 +436,12 @@ static void populateFromPattern(FcPattern *pattern) } #if FC_VERSION >= 20297 + FcChar8 *cap = Q_NULLPTR; for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) { if (writingSystems.supported(QFontDatabase::WritingSystem(j)) && requiresOpenType(j) && openType[j]) { - FcChar8 *cap; - res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap); + if (cap == Q_NULLPTR) + res = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap); if (res == FcResultMatch && strstr(reinterpret_cast(cap), openType[j]) == 0) writingSystems.setSupported(QFontDatabase::WritingSystem(j),false); } -- cgit v1.2.3 From db2764db3466221ad680d63ff2224cdd016fc351 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 27 Apr 2016 15:18:29 +0400 Subject: Get rid of requiresOpenType() helper There is already an array of writing systems for which GSUB|GPOS table is required (also rename it from "openType" to "capabilityForWritingSystem", to reflect its meaning). Change-Id: I7cfd4a80d5ca13f9312b3644b2bd738d6015c71c Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontconfig/qfontconfigdatabase.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index c15e0a1183..ca79224850 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -62,12 +62,6 @@ static inline int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper, return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower); } -static inline bool requiresOpenType(int writingSystem) -{ - return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala) - || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko); -} - static inline int weightFromFcWeight(int fcweight) { // Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from @@ -293,10 +287,10 @@ static const char *languageForWritingSystem[] = { Q_STATIC_ASSERT(sizeof(languageForWritingSystem) / sizeof(const char *) == QFontDatabase::WritingSystemsCount); #if FC_VERSION >= 20297 -// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no -// open type tables for is directly. Do this so we don't pick some strange -// pseudo unicode font -static const char *openType[] = { +// Newer FontConfig let's us sort out fonts that report certain scripts support, +// but no open type tables for handling them correctly. +// Check the reported script presence in the FC_CAPABILITY's "otlayout:" section. +static const char *capabilityForWritingSystem[] = { 0, // Any 0, // Latin 0, // Greek @@ -332,7 +326,7 @@ static const char *openType[] = { 0, // Runic "nko " // N'Ko }; -Q_STATIC_ASSERT(sizeof(openType) / sizeof(const char *) == QFontDatabase::WritingSystemsCount); +Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount); #endif static const char *getFcFamilyForStyleHint(const QFont::StyleHint style) @@ -438,11 +432,10 @@ static void populateFromPattern(FcPattern *pattern) #if FC_VERSION >= 20297 FcChar8 *cap = Q_NULLPTR; for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) { - if (writingSystems.supported(QFontDatabase::WritingSystem(j)) - && requiresOpenType(j) && openType[j]) { + if (capabilityForWritingSystem[j] && writingSystems.supported(QFontDatabase::WritingSystem(j))) { if (cap == Q_NULLPTR) res = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap); - if (res == FcResultMatch && strstr(reinterpret_cast(cap), openType[j]) == 0) + if (res == FcResultMatch && strstr(reinterpret_cast(cap), capabilityForWritingSystem[j]) == 0) writingSystems.setSupported(QFontDatabase::WritingSystem(j),false); } } -- cgit v1.2.3 From 4c6324b5a770254ac66f80583bcdce9cb5e282c4 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 27 Apr 2016 15:25:07 +0400 Subject: Micro optimization to QFontconfigDatabase Do not set WritingSystem supported just to unset it afterwards; test in-place and fallback gracefully. Change-Id: I6910019c08fcf3909b924c27271547aae2ea0ff1 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontconfig/qfontconfigdatabase.cpp | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index ca79224850..8ebabf3419 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -409,11 +409,23 @@ static void populateFromPattern(FcPattern *pattern) FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset); if (res == FcResultMatch) { bool hasLang = false; +#if FC_VERSION >= 20297 + FcChar8 *cap = Q_NULLPTR; + FcResult capRes = FcResultNoMatch; +#endif for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) { const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j]; if (lang) { FcLangResult langRes = FcLangSetHasLang(langset, lang); if (langRes != FcLangDifferentLang) { +#if FC_VERSION >= 20297 + if (capabilityForWritingSystem[j] != Q_NULLPTR) { + if (cap == Q_NULLPTR) + capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap); + if (capRes == FcResultMatch && strstr(reinterpret_cast(cap), capabilityForWritingSystem[j]) == 0) + continue; + } +#endif writingSystems.setSupported(QFontDatabase::WritingSystem(j)); hasLang = true; } @@ -429,18 +441,6 @@ static void populateFromPattern(FcPattern *pattern) writingSystems.setSupported(QFontDatabase::Other); } -#if FC_VERSION >= 20297 - FcChar8 *cap = Q_NULLPTR; - for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) { - if (capabilityForWritingSystem[j] && writingSystems.supported(QFontDatabase::WritingSystem(j))) { - if (cap == Q_NULLPTR) - res = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap); - if (res == FcResultMatch && strstr(reinterpret_cast(cap), capabilityForWritingSystem[j]) == 0) - writingSystems.setSupported(QFontDatabase::WritingSystem(j),false); - } - } -#endif - FontFile *fontFile = new FontFile; fontFile->fileName = QString::fromLocal8Bit((const char *)file_value); fontFile->indexValue = indexValue; -- cgit v1.2.3 From ab06266e15265737039cec2129fdf44848ed95a8 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 25 Apr 2016 15:19:53 +0200 Subject: Fix clipping of wave underline decoration on certain fonts Limit the height of the the wave-pixmap so that fillRect doesn't clip it. At the same time the precision of the generated wave-pixmap is improved so it better fits the requested radius. Task-number: QTCREATORBUG-15851 Change-Id: If754387b20ab7b015857ecb0a0e8fe16de1d728a Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qpainter.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 5dcab11f0a..baeee4dbfa 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6179,7 +6179,8 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) QString key = QLatin1String("WaveUnderline-") % pen.color().name() - % HexString(radiusBase); + % HexString(radiusBase) + % HexString(pen.widthF()); QPixmap pixmap; if (QPixmapCache::find(key, pixmap)) @@ -6187,7 +6188,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod); - const int radius = qFloor(radiusBase); + const qreal radius = qFloor(radiusBase * 2) / 2.; QPainterPath path; @@ -6210,7 +6211,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) // due to it having a rather thick width for the regular underline. const qreal maxPenWidth = .8 * radius; if (wavePen.widthF() > maxPenWidth) - wavePen.setWidth(maxPenWidth); + wavePen.setWidthF(maxPenWidth); QPainter imgPainter(&pixmap); imgPainter.setPen(wavePen); @@ -6263,14 +6264,15 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const if (underlineStyle == QTextCharFormat::WaveUnderline) { painter->save(); painter->translate(0, pos.y() + 1); + qreal maxHeight = fe->descent().toReal() - qreal(1); QColor uc = charFormat.underlineColor(); if (uc.isValid()) pen.setColor(uc); // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms - const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen); - const int descent = (int) fe->descent().toReal(); + const QPixmap wave = generateWavyPixmap(qMin(qMax(underlineOffset, pen.widthF()), maxHeight / 2.), pen); + const int descent = qFloor(maxHeight); painter->setBrushOrigin(painter->brushOrigin().x(), 0); painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave); -- cgit v1.2.3 From ef7b0df4192b390c70a5e848bbe7c397daaefcce Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 26 Apr 2016 14:56:32 -0700 Subject: Fix QArrayData::allocate() to guard against integer overflows The proper solution with qCalculateBlockSize will come for Qt 5.7. Change-Id: Ifea6e497f11a461db432ffff14490788fc522eb7 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qarraydata.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index d9519745b0..fa6556f7d9 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include +#include #include #include @@ -87,16 +88,22 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, if (capacity > std::numeric_limits::max() / objectSize) return 0; - size_t alloc = objectSize * capacity; + size_t alloc; + if (mul_overflow(objectSize, capacity, &alloc)) + return 0; - // Make sure qAllocMore won't overflow. + // Make sure qAllocMore won't overflow qAllocMore. if (headerSize > size_t(MaxAllocSize) || alloc > size_t(MaxAllocSize) - headerSize) return 0; capacity = qAllocMore(int(alloc), int(headerSize)) / int(objectSize); } - size_t allocSize = headerSize + objectSize * capacity; + size_t allocSize; + if (mul_overflow(objectSize, capacity, &allocSize)) + return 0; + if (add_overflow(allocSize, headerSize, &allocSize)) + return 0; QArrayData *header = static_cast(::malloc(allocSize)); if (header) { -- cgit v1.2.3 From 3430552881ccd75b4f00c62014b7fa810c998002 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 24 Apr 2016 12:57:25 -0700 Subject: Use C++11 alignas() for Q_DECL_ALIGN, if possible Change-Id: Ifea6e497f11a461db432ffff144863d4ed69a212 Reviewed-by: Marc Mutz --- src/corelib/global/qcompilerdetection.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 25043dab75..8574059616 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1055,6 +1055,11 @@ # define Q_ALIGNOF(x) alignof(x) #endif +#if defined(Q_COMPILER_ALIGNAS) +# undef Q_DECL_ALIGN +# define Q_DECL_ALIGN(n) alignas(n) +#endif + /* * Fallback macros to certain compiler features */ -- cgit v1.2.3 From 9e52234da16ba9a82bae5221b9e52dd08b4e712e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sun, 24 Apr 2016 17:13:24 +0100 Subject: Fix clang developer build due to -Winconsistent-missing-override The existing code keeps the overrides from each base class together, so also move them to the correct group after adding Q_DECL_OVERRIDE. Change-Id: I5d89fb4e7f9454ab0c9c6383f8245e64b95e84e9 Reviewed-by: Marc Mutz Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qdatetimeedit_p.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h index 5772647a1a..57bb9d2104 100644 --- a/src/widgets/widgets/qdatetimeedit_p.h +++ b/src/widgets/widgets/qdatetimeedit_p.h @@ -72,15 +72,14 @@ public: void init(const QVariant &var); void readLocaleSettings(); - void emitSignals(EmitPolicy ep, const QVariant &old); - QString textFromValue(const QVariant &f) const; - QVariant valueFromText(const QString &f) const; - QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state, bool fixup = false) const; void clearSection(int index); // Override QAbstractSpinBoxPrivate: + void emitSignals(EmitPolicy ep, const QVariant &old) Q_DECL_OVERRIDE; + QString textFromValue(const QVariant &f) const Q_DECL_OVERRIDE; + QVariant valueFromText(const QString &f) const Q_DECL_OVERRIDE; void _q_editorCursorPositionChanged(int oldpos, int newpos) Q_DECL_OVERRIDE; void interpret(EmitPolicy ep) Q_DECL_OVERRIDE; void clearCache() const Q_DECL_OVERRIDE; @@ -88,16 +87,18 @@ public: void updateEditFieldGeometry() Q_DECL_OVERRIDE; QVariant getZeroVariant() const Q_DECL_OVERRIDE; void setRange(const QVariant &min, const QVariant &max) Q_DECL_OVERRIDE; + void updateEdit() Q_DECL_OVERRIDE; - // Override QDateTimePraser: + // Override QDateTimeParser: QString displayText() const Q_DECL_OVERRIDE { return edit->text(); } QDateTime getMinimum() const Q_DECL_OVERRIDE { return minimum.toDateTime(); } QDateTime getMaximum() const Q_DECL_OVERRIDE { return maximum.toDateTime(); } QLocale locale() const Q_DECL_OVERRIDE { return q_func()->locale(); } + QString getAmPmText(AmPm ap, Case cs) const Q_DECL_OVERRIDE; + int cursorPosition() const Q_DECL_OVERRIDE { return edit ? edit->cursorPosition() : -1; } int absoluteIndex(QDateTimeEdit::Section s, int index) const; int absoluteIndex(const SectionNode &s) const; - void updateEdit(); QDateTime stepBy(int index, int steps, bool test = false) const; int sectionAt(int pos) const; int closestSection(int index, bool forward) const; @@ -108,8 +109,6 @@ public: void updateTimeSpec(); QString valueToText(const QVariant &var) const { return textFromValue(var); } - QString getAmPmText(AmPm ap, Case cs) const; - int cursorPosition() const { return edit ? edit->cursorPosition() : -1; } void _q_resetButton(); void updateArrow(QStyle::StateFlag state); -- cgit v1.2.3 From 52e68d4e106548eb027d4b35e47c941eb2d73f58 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 25 Apr 2016 12:29:20 +0200 Subject: winrt: Fix memory leak for file reading IInputStream::ReadAsync might create a separate buffer to fill in data. Passing a buffer with GetAddressOf() can cause a memory leak of the size of data to be read. Instead, pass a separate buffer pointer and continue to use this one after the async operation. This way, the OS can decide whether to switch buffers or not, keeping ref counting in sync. Task-number: QTBUG-52961 Change-Id: I9dfb627287142355ebcf74ca52427b4e8108e8d1 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtfileengine.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index 858cb841b9..fb7c5e9990 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -463,14 +463,20 @@ qint64 QWinRTFileEngine::read(char *data, qint64 maxlen) hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); - hr = QWinRTFunctions::await(op, buffer.GetAddressOf()); + // Quoting MSDN IInputStream::ReadAsync() documentation: + // "Depending on the implementation, the data that's read might be placed + // into the input buffer, or it might be returned in a different buffer." + // Using GetAddressOf can cause ref counting errors leaking the original + // buffer. + ComPtr effectiveBuffer; + hr = QWinRTFunctions::await(op, effectiveBuffer.GetAddressOf()); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); - hr = buffer->get_Length(&length); + hr = effectiveBuffer->get_Length(&length); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); ComPtr byteArrayAccess; - hr = buffer.As(&byteArrayAccess); + hr = effectiveBuffer.As(&byteArrayAccess); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); byte *bytes; -- cgit v1.2.3 From 8a7311532ba331252d87cbcc08ea676f106242e9 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 27 Apr 2016 10:19:42 +0200 Subject: winrt: Refactor pointer device handling to support pen In addition to pen events being handled as tablet events, we create touch events. Same principle is used on other platforms as well. This allows devices as Surfaces to use the pen with Qt applications. Furthermore, the first update event does not have to be a press event, as in a pen has proximity values describing a move without touch, but also the HoloLens uses touch points as permanent pointer devices. They all send an exit event once released or out of range. Hence, clean up the internal touchpoint hash when the touch device is gone, not on release. Task-number: QTBUG-38681 Change-Id: I38acaa034a3cfe224098bfa36bfead5428f4db16 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 67 +++++++++++++++------------- 1 file changed, 37 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 7fe8362817..0255527e91 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -952,8 +952,20 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args) return S_OK; } -HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *) +HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args) { + Q_D(QWinRTScreen); + + ComPtr pointerPoint; + if (FAILED(args->get_CurrentPoint(&pointerPoint))) + return E_INVALIDARG; + + quint32 id; + if (FAILED(pointerPoint->get_PointerId(&id))) + return E_INVALIDARG; + + d->touchPoints.remove(id); + QWindowSystemInterface::handleLeaveEvent(0); return S_OK; } @@ -1037,6 +1049,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) break; } + case PointerDeviceType_Pen: case PointerDeviceType_Touch: { if (!d->touchDevice) { d->touchDevice = new QTouchDevice; @@ -1055,51 +1068,45 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) float pressure; properties->get_Pressure(&pressure); - QHash::iterator it = d->touchPoints.find(id); - if (it != d->touchPoints.end()) { - boolean isPressed; + boolean isPressed; #ifndef Q_OS_WINPHONE - pointerPoint->get_IsInContact(&isPressed); + pointerPoint->get_IsInContact(&isPressed); #else - properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone + properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone #endif - it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased; - } else { + + const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor, + area.Width * d->scaleFactor, area.Height * d->scaleFactor); + + QHash::iterator it = d->touchPoints.find(id); + if (it == d->touchPoints.end()) { it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint()); - it.value().state = Qt::TouchPointPressed; it.value().id = id; } - it.value().area = QRectF(area.X * d->scaleFactor, area.Y * d->scaleFactor, - area.Width * d->scaleFactor, area.Height * d->scaleFactor); + + if (isPressed && it.value().pressure == 0.) + it.value().state = Qt::TouchPointPressed; + else if (!isPressed && it.value().pressure > 0.) + it.value().state = Qt::TouchPointReleased; + else if (it.value().area == areaRect) + it.value().state = Qt::TouchPointStationary; + else + it.value().state = Qt::TouchPointMoved; + + it.value().area = areaRect; it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height()); it.value().pressure = pressure; QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods); - // Remove released points, station others - for (QHash::iterator i = d->touchPoints.begin(); i != d->touchPoints.end();) { - if (i.value().state == Qt::TouchPointReleased) - i = d->touchPoints.erase(i); - else - (i++).value().state = Qt::TouchPointStationary; - } - - break; - } - case PointerDeviceType_Pen: { - quint32 id; - pointerPoint->get_PointerId(&id); - - boolean isPressed; - pointerPoint->get_IsInContact(&isPressed); + // Fall-through for pen to generate tablet event + if (pointerDeviceType != PointerDeviceType_Pen) + break; boolean isEraser; properties->get_IsEraser(&isEraser); int pointerType = isEraser ? 3 : 1; - float pressure; - properties->get_Pressure(&pressure); - float xTilt; properties->get_XTilt(&xTilt); -- cgit v1.2.3 From 9be4ee52021bbb3227611979319ab5e3106063b2 Mon Sep 17 00:00:00 2001 From: Weng Xuetian Date: Thu, 3 Mar 2016 21:56:53 -0800 Subject: QtDBus: finish all pending call with error if disconnected libdbus will send a local signal if connection gets disconnected. When this happens, end all pending calls with QDBusError::Disconnected. Task-number: QTBUG-51649 Change-Id: I5c7d2a468bb5da746d0c0e53e458c1e376f186a9 Reviewed-by: Thiago Macieira --- src/dbus/dbus_minimal_p.h | 2 ++ src/dbus/qdbusconnection_p.h | 3 +++ src/dbus/qdbusintegrator.cpp | 41 +++++++++++++++++++++++++++++++++++------ src/dbus/qdbusutil_p.h | 2 ++ 4 files changed, 42 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h index f0a29540c8..8f25b24c61 100644 --- a/src/dbus/dbus_minimal_p.h +++ b/src/dbus/dbus_minimal_p.h @@ -99,9 +99,11 @@ typedef dbus_uint32_t dbus_bool_t; /* dbus-shared.h */ #define DBUS_SERVICE_DBUS "org.freedesktop.DBus" #define DBUS_PATH_DBUS "/org/freedesktop/DBus" +#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" #define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" #define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" +#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local" #define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */ #define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */ diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 565eb832f2..b733a68856 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -260,6 +260,8 @@ private: QString getNameOwnerNoCache(const QString &service); + void watchForDBusDisconnection(); + void _q_newConnection(QDBusConnectionPrivate *newConnection); protected: @@ -279,6 +281,7 @@ private slots: void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner); void registerServiceNoLock(const QString &serviceName); void unregisterServiceNoLock(const QString &serviceName); + void handleDBusDisconnection(); signals: void dispatchStatusChanged(); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 3be775db82..d0468f4af0 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1121,6 +1121,12 @@ void QDBusConnectionPrivate::closeConnection() rootNode.children.clear(); // free resources } +void QDBusConnectionPrivate::handleDBusDisconnection() +{ + while (!pendingCalls.isEmpty()) + processFinishedCall(pendingCalls.first()); +} + void QDBusConnectionPrivate::checkThread() { Q_ASSERT(thread() == QDBusConnectionManager::instance()); @@ -1646,6 +1652,19 @@ void QDBusConnectionPrivate::handleSignal(const QDBusMessage& msg) handleSignal(key, msg); // third try } +void QDBusConnectionPrivate::watchForDBusDisconnection() +{ + SignalHook hook; + // Initialize the hook for Disconnected signal + hook.service.clear(); // org.freedesktop.DBus.Local.Disconnected uses empty service name + hook.path = QDBusUtil::dbusPathLocal(); + hook.obj = this; + hook.params << QMetaType::Void; + hook.midx = staticMetaObject.indexOfSlot("handleDBusDisconnection()"); + Q_ASSERT(hook.midx != -1); + signalHooks.insert(QLatin1String("Disconnected:" DBUS_INTERFACE_LOCAL), hook); +} + void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s, const QDBusErrorInternal &error) { mode = ServerMode; @@ -1711,6 +1730,8 @@ void QDBusConnectionPrivate::setPeer(DBusConnection *c, const QDBusErrorInternal qDBusSignalFilter, this, 0); + watchForDBusDisconnection(); + QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection); } @@ -1787,6 +1808,8 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError Q_ASSERT(hook.midx != -1); signalHooks.insert(QLatin1String("NameOwnerChanged:" DBUS_INTERFACE_DBUS), hook); + watchForDBusDisconnection(); + qDBusDebug() << this << ": connected successfully"; // schedule a dispatch: @@ -1813,10 +1836,16 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) QDBusMessage &msg = call->replyMessage; if (call->pending) { - // decode the message - DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending); - msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities); - q_dbus_message_unref(reply); + // when processFinishedCall is called and pending call is not completed, + // it means we received disconnected signal from libdbus + if (q_dbus_pending_call_get_completed(call->pending)) { + // decode the message + DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending); + msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities); + q_dbus_message_unref(reply); + } else { + msg = QDBusMessage::createError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage()); + } } qDBusDebug() << connection << "got message reply:" << msg; @@ -2116,8 +2145,8 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void * pcall->pending = pending; q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0); - // DBus won't notify us when a peer disconnects so we need to track these ourselves - if (mode == QDBusConnectionPrivate::PeerMode) + // DBus won't notify us when a peer disconnects or server terminates so we need to track these ourselves + if (mode == QDBusConnectionPrivate::PeerMode || mode == QDBusConnectionPrivate::ClientMode) pendingCalls.append(pcall); return; diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h index 8f5ae922db..f4ab9b9b1f 100644 --- a/src/dbus/qdbusutil_p.h +++ b/src/dbus/qdbusutil_p.h @@ -155,6 +155,8 @@ namespace QDBusUtil { return QStringLiteral(DBUS_SERVICE_DBUS); } inline QString dbusPath() { return QStringLiteral(DBUS_PATH_DBUS); } + inline QString dbusPathLocal() + { return QStringLiteral(DBUS_PATH_LOCAL); } inline QString dbusInterface() { // it's the same string, but just be sure -- cgit v1.2.3 From 9a7e967e99957668f7846763ce592f54d94b9a71 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 18 Apr 2016 18:46:13 +0300 Subject: Unhide QObject::parent() from QFileSystemModel and QIdentityProxyModel It was hidden by overridden parent(const QModelIndex &) methods. See also 63b5082ea8e3e750af986f815474f7207006cb46 (Unhide QObject::parent() from QAbstract{Table,List}model). Change-Id: I8b6d4d4175e4d43ff269eaeb0b2b1a9fb8f44bab Task-number: QTBUG-45393 Reviewed-by: Milian Wolff Reviewed-by: Marc Mutz --- src/corelib/itemmodels/qidentityproxymodel.h | 1 + src/widgets/dialogs/qfilesystemmodel.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h index 7578f8d380..395fec11cb 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.h +++ b/src/corelib/itemmodels/qidentityproxymodel.h @@ -56,6 +56,7 @@ public: QModelIndex mapFromSource(const QModelIndex& sourceIndex) const Q_DECL_OVERRIDE; QModelIndex mapToSource(const QModelIndex& proxyIndex) const Q_DECL_OVERRIDE; QModelIndex parent(const QModelIndex& child) const Q_DECL_OVERRIDE; + using QObject::parent; int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) Q_DECL_OVERRIDE; diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h index 515417f225..5536d2b87c 100644 --- a/src/widgets/dialogs/qfilesystemmodel.h +++ b/src/widgets/dialogs/qfilesystemmodel.h @@ -75,6 +75,7 @@ public: QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QModelIndex index(const QString &path, int column = 0) const; QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE; + using QObject::parent; bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE; void fetchMore(const QModelIndex &parent) Q_DECL_OVERRIDE; -- cgit v1.2.3 From 8c2b7405b4a5f7d0fee62b78a17100529e611a5c Mon Sep 17 00:00:00 2001 From: Kai Pastor Date: Sun, 24 Apr 2016 19:52:37 +0200 Subject: QPdf: Force miter limit into valid range Miter limits below 1.0 are not valid in PDF and trigger an error in the Reader. This change enforces a minimum miter limit of 1.0, and it adds a manual test for producing a PDF file demonstrating this issue. Task-number: QTBUG-52641 Change-Id: I1c78b1c4a44579e95e1cddfb459926d304e60165 Reviewed-by: Lars Knoll --- src/gui/painting/qpdf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 22a387bd28..0df5fd8b8a 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1196,7 +1196,7 @@ void QPdfEngine::setPen() switch(d->pen.joinStyle()) { case Qt::MiterJoin: case Qt::SvgMiterJoin: - *d->currentPage << d->pen.miterLimit() << "M "; + *d->currentPage << qMax(qreal(1.0), d->pen.miterLimit()) << "M "; pdfJoinStyle = 0; break; case Qt::BevelJoin: -- cgit v1.2.3 From 31915a1805d61c512fad57585315a895d4543e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 26 Apr 2016 16:59:37 +0100 Subject: qstyle: Make image description match the image. The image shows 9 combo boxes, not 8. Change-Id: If229332e1708f624ad9f50fab0b78c011d94f31e Reviewed-by: Martin Smith --- src/widgets/styles/qstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 4a601ba871..97ed8eec3d 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -151,10 +151,10 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C Qt's built-in widgets use QStyle to perform nearly all of their drawing, ensuring that they look exactly like the equivalent - native widgets. The diagram below shows a QComboBox in eight + native widgets. The diagram below shows a QComboBox in nine different styles. - \image qstyle-comboboxes.png Eight combo boxes + \image qstyle-comboboxes.png Nine combo boxes Topics: -- cgit v1.2.3 From 89d1c7c179aea55bd991b524bdcc9c3e265510fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 19 Apr 2016 13:33:46 +0100 Subject: Make it clear that QObject::tr() falls back to QString::fromUtf8() The reference to trUtf8() made it even more confusing, so remove it. It's redundant and deprecated anyway. Change-Id: I9921297160db3660bb5099692bbfdaf6e85637aa Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qobject.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 5afdd6a4e5..19df24744a 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2144,8 +2144,8 @@ void QObject::deleteLater() Returns a translated version of \a sourceText, optionally based on a \a disambiguation string and value of \a n for strings containing plurals; - otherwise returns \a sourceText itself if no appropriate translated string - is available. + otherwise returns QString::fromUtf8(\a sourceText) if no appropriate + translated string is available. Example: \snippet ../widgets/mainwindows/sdi/mainwindow.cpp implicit tr context @@ -2171,7 +2171,7 @@ void QObject::deleteLater() translators while performing translations is not supported. Doing so will probably result in crashes or other undesirable behavior. - \sa trUtf8(), QCoreApplication::translate(), {Internationalization with Qt} + \sa QCoreApplication::translate(), {Internationalization with Qt} */ /*! -- cgit v1.2.3 From 002112e80516a29efbb6cef721d74c5fc39fc19d Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 28 Apr 2016 14:28:08 +0200 Subject: Fix scroll regression near scroll-view ends Fix regression in a7b0cb467ca5c4a9447d049910c9e3f0abc5897c which caused it to be hard to start scrolling at the ends of a scroll-view if using fine grained scrolling events. Change-Id: I55f3210150b993281545c3ad5a7356d892fa30b5 Reviewed-by: Simon Hausmann --- src/widgets/widgets/qabstractslider.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp index 92d2ffde2b..d818d0b6a9 100644 --- a/src/widgets/widgets/qabstractslider.cpp +++ b/src/widgets/widgets/qabstractslider.cpp @@ -723,9 +723,10 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb if (stepsToScroll == 0) { // We moved less than a line, but might still have accumulated partial scroll, // unless we already are at one of the ends. - if (offset_accumulated > 0.f && value < maximum) + const float effective_offset = invertedControls ? -offset_accumulated : offset_accumulated; + if (effective_offset > 0.f && value < maximum) return true; - if (offset_accumulated < 0.f && value > minimum) + if (effective_offset < 0.f && value > minimum) return true; offset_accumulated = 0; return false; -- cgit v1.2.3