diff options
30 files changed, 221 insertions, 67 deletions
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 674742fbf6..42250b629d 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -160,15 +160,9 @@ QFSFileEngine::~QFSFileEngine() Q_D(QFSFileEngine); if (d->closeFileHandle) { if (d->fh) { - int ret; - do { - ret = fclose(d->fh); - } while (ret == EOF && errno == EINTR); + fclose(d->fh); } else if (d->fd != -1) { - int ret; - do { - ret = QT_CLOSE(d->fd); - } while (ret == -1 && errno == EINTR); + QT_CLOSE(d->fd); } } d->unmapAll(); @@ -365,15 +359,14 @@ bool QFSFileEnginePrivate::closeFdFh() // Close the file if we created the handle. if (closeFileHandle) { int ret; - do { - if (fh) { - // Close buffered file. - ret = fclose(fh) != 0 ? -1 : 0; - } else { - // Close unbuffered file. - ret = QT_CLOSE(fd); - } - } while (ret == -1 && errno == EINTR); + + if (fh) { + // Close buffered file. + ret = fclose(fh); + } else { + // Close unbuffered file. + ret = QT_CLOSE(fd); + } // We must reset these guys regardless; calling close again after a // failed close causes crashes on some systems. diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 01a70720ee..f6cd5aa7c9 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -672,11 +672,11 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result, } } -inline static void iniChopTrailingSpaces(QString &str) +inline static void iniChopTrailingSpaces(QString &str, int limit) { int n = str.size() - 1; QChar ch; - while (n >= 0 && ((ch = str.at(n)) == QLatin1Char(' ') || ch == QLatin1Char('\t'))) + while (n >= limit && ((ch = str.at(n)) == QLatin1Char(' ') || ch == QLatin1Char('\t'))) str.truncate(n--); } @@ -734,6 +734,7 @@ StSkipSpaces: // fallthrough StNormal: + int chopLimit = stringResult.length(); while (i < to) { switch (str.at(i)) { case '\\': @@ -771,6 +772,7 @@ StNormal: } else { // the character is skipped } + chopLimit = stringResult.length(); break; case '"': ++i; @@ -782,7 +784,7 @@ StNormal: case ',': if (!inQuotedString) { if (!currentValueIsQuoted) - iniChopTrailingSpaces(stringResult); + iniChopTrailingSpaces(stringResult, chopLimit); if (!isStringList) { isStringList = true; stringListResult.clear(); @@ -822,6 +824,8 @@ StNormal: } } } + if (!currentValueIsQuoted) + iniChopTrailingSpaces(stringResult, chopLimit); goto end; StHexEscape: @@ -861,8 +865,6 @@ StOctEscape: } end: - if (!currentValueIsQuoted) - iniChopTrailingSpaces(stringResult); if (isStringList) stringListResult.append(stringResult); return isStringList; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 65b22021fd..e3e0f570e7 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1465,14 +1465,14 @@ void QObject::moveToThread(QThread *targetThread) } QThreadData *currentData = QThreadData::current(); - QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : new QThreadData(0); + QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : Q_NULLPTR; if (d->threadData->thread == 0 && currentData == targetData) { // one exception to the rule: we allow moving objects with no thread affinity to the current thread currentData = d->threadData; } else if (d->threadData != currentData) { qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n" "Cannot move to target thread (%p)\n", - currentData->thread, d->threadData->thread, targetData->thread); + currentData->thread, d->threadData->thread, targetData ? targetData->thread : Q_NULLPTR); #ifdef Q_OS_MAC qWarning("On Mac OS X, you might be loading two sets of Qt binaries into the same process. " @@ -1486,6 +1486,9 @@ void QObject::moveToThread(QThread *targetThread) // prepare to move d->moveToThread_helper(); + if (!targetData) + targetData = new QThreadData(0); + QOrderedMutexLocker locker(¤tData->postEventList.mutex, &targetData->postEventList.mutex); diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc index 6966047c13..92f21fc512 100644 --- a/src/corelib/thread/qfuture.qdoc +++ b/src/corelib/thread/qfuture.qdoc @@ -89,7 +89,7 @@ /*! \fn QFuture::QFuture() - Constructs an empty future. + Constructs an empty, canceled future. */ /*! \fn QFuture::QFuture(const QFuture &other) diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 64a6cd8602..bfa628900f 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -1354,8 +1354,7 @@ void dither_to_Mono(QImageData *dst, const QImageData *src, dst_data += dst_bpl; src_data += src_bpl; } - } else - /* (d == 8) */ { + } else if (d == 8) { for (int i=0; i<h; i++) { const uchar *p = src_data; const uchar *end = p + w; diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index 1191f27ad7..3f2da7af28 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -3558,8 +3558,10 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule) return region; } - if (!(pETEs = static_cast<EdgeTableEntry *>(malloc(sizeof(EdgeTableEntry) * Count)))) + if (!(pETEs = static_cast<EdgeTableEntry *>(malloc(sizeof(EdgeTableEntry) * Count)))) { + delete region; return 0; + } region->vectorize(); diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index f597ea0e9e..04a97aabcb 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -250,6 +250,7 @@ QTransform::QTransform() , m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxNone) + , d(Q_NULLPTR) { } @@ -268,6 +269,7 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13, , m_13(h13), m_23(h23), m_33(h33) , m_type(TxNone) , m_dirty(TxProject) + , d(Q_NULLPTR) { } @@ -284,6 +286,7 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h21, , m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxShear) + , d(Q_NULLPTR) { } @@ -299,6 +302,7 @@ QTransform::QTransform(const QMatrix &mtx) m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxShear) + , d(Q_NULLPTR) { } diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index e32e29c5da..68c4548644 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -154,12 +154,18 @@ private: : affine(h11, h12, h21, h22, h31, h32, true) , m_13(h13), m_23(h23), m_33(h33) , m_type(TxNone) - , m_dirty(TxProject) {} + , m_dirty(TxProject) + , d(Q_NULLPTR) + { + } inline QTransform(bool) : affine(true) , m_13(0), m_23(0), m_33(1) , m_type(TxNone) - , m_dirty(TxNone) {} + , m_dirty(TxNone) + , d(Q_NULLPTR) + { + } inline TransformationType inline_type() const; QMatrix affine; qreal m_13; diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 70558a7cc4..9fe1fd26e9 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2519,6 +2519,7 @@ bool QTextEngine::atWordSeparator(int position) const case '`': case '~': case '|': + case '\\': return true; default: break; diff --git a/src/network/access/qnetworkaccesscachebackend.cpp b/src/network/access/qnetworkaccesscachebackend.cpp index 86b544052d..0a9702d32b 100644 --- a/src/network/access/qnetworkaccesscachebackend.cpp +++ b/src/network/access/qnetworkaccesscachebackend.cpp @@ -44,7 +44,6 @@ QT_BEGIN_NAMESPACE QNetworkAccessCacheBackend::QNetworkAccessCacheBackend() : QNetworkAccessBackend() - , device(0) { } @@ -117,11 +116,6 @@ bool QNetworkAccessCacheBackend::sendCacheContents() void QNetworkAccessCacheBackend::closeDownstreamChannel() { - if (operation() == QNetworkAccessManager::GetOperation) { - device->close(); - delete device; - device = 0; - } } void QNetworkAccessCacheBackend::closeUpstreamChannel() diff --git a/src/network/access/qnetworkaccesscachebackend_p.h b/src/network/access/qnetworkaccesscachebackend_p.h index b0209c453f..f298b84471 100644 --- a/src/network/access/qnetworkaccesscachebackend_p.h +++ b/src/network/access/qnetworkaccesscachebackend_p.h @@ -67,7 +67,6 @@ public: private: bool sendCacheContents(); - QIODevice *device; }; diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 2af23a4eb5..a021d51952 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -424,6 +424,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate() , synchronous(false) , state(Idle) , statusCode(0) + , uploadDeviceChoking(false) , outgoingData(0) , bytesUploaded(-1) , cacheLoadDevice(0) @@ -1285,9 +1286,12 @@ void QNetworkReplyHttpImplPrivate::wantUploadDataSlot(qint64 maxSize) char *data = const_cast<char*>(uploadByteDevice->readPointer(maxSize, currentUploadDataLength)); if (currentUploadDataLength == 0) { + uploadDeviceChoking = true; // No bytes from upload byte device. There will be bytes later, it will emit readyRead() // and our uploadByteDeviceReadyReadSlot() is called. return; + } else { + uploadDeviceChoking = false; } // Let's make a copy of this data @@ -1300,7 +1304,12 @@ void QNetworkReplyHttpImplPrivate::wantUploadDataSlot(qint64 maxSize) void QNetworkReplyHttpImplPrivate::uploadByteDeviceReadyReadSlot() { // Start the flow between this thread and the HTTP thread again by triggering a upload. - wantUploadDataSlot(1024); + // However only do this when we were choking before, else the state in + // QNonContiguousByteDeviceThreadForwardImpl gets messed up. + if (uploadDeviceChoking) { + uploadDeviceChoking = false; + wantUploadDataSlot(1024); + } } diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index 6ef2842ee9..baff7a943c 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -194,6 +194,7 @@ public: // upload QNonContiguousByteDevice* createUploadByteDevice(); QSharedPointer<QNonContiguousByteDevice> uploadByteDevice; + bool uploadDeviceChoking; // if we couldn't readPointer() any data at the moment QIODevice *outgoingData; QSharedPointer<QRingBuffer> outgoingDataBuffer; void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal); // dup? diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 6d0a30d366..60f971a2fb 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -139,13 +139,13 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; int socket = qt_safe_socket(protocol, type, 0); - if (socket <= 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) { + if (socket < 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) { protocol = AF_INET; socket = qt_safe_socket(protocol, type, 0); socketProtocol = QAbstractSocket::IPv4Protocol; } - if (socket <= 0) { + if (socket < 0) { int ecopy = errno; switch (ecopy) { case EPROTONOSUPPORT: diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index f021446438..78465b896d 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -703,9 +703,8 @@ bool QCocoaFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() { - if (mDelegate) - return; QCocoaAutoReleasePool pool; + const SharedPointerFileDialogOptions &opts = options(); const QList<QUrl> selectedFiles = opts->initiallySelectedFiles(); const QUrl directory = mDir.isEmpty() ? opts->initialDirectory() : mDir; @@ -717,6 +716,7 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() options:opts helper:this]; + [static_cast<QNSOpenSavePanelDelegate *>(mDelegate) release]; mDelegate = delegate; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 7e22351818..a0e02501de 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -82,6 +82,32 @@ static bool isMouseEvent(NSEvent *ev) } } +static void selectNextKeyWindow(NSWindow *currentKeyWindow) +{ + if (!currentKeyWindow) + return; + + const QCocoaAutoReleasePool pool; + + if ([[NSApplication sharedApplication] keyWindow] != currentKeyWindow) + return;//currentKeyWindow is not a key window actually. + + NSArray *const windows = [[NSApplication sharedApplication] windows]; + bool startLookup = false; + for (NSWindow *candidate in [windows reverseObjectEnumerator]) { + if (!startLookup) { + if (candidate == currentKeyWindow) + startLookup = true; + } else { + if ([candidate isVisible] && [candidate canBecomeKeyWindow]) { + [candidate makeKeyWindow]; + break; + } + } + } +} + + @interface NSWindow (CocoaWindowCategory) - (NSRect) legacyConvertRectFromScreen:(NSRect) rect; @end @@ -592,6 +618,9 @@ void QCocoaWindow::hide(bool becauseOfAncestor) foreach (QCocoaWindow *childWindow, m_childWindows) childWindow->hide(true); + if (window()->transientParent() && m_nsWindow == [[NSApplication sharedApplication] keyWindow]) + selectNextKeyWindow(m_nsWindow); // Otherwise, Cocoa can do it wrong. + [m_nsWindow orderOut:nil]; } @@ -1456,7 +1485,11 @@ void QCocoaWindow::setNSWindow(QCocoaNSWindow *window) { if (window.contentView != m_contentView) { [m_contentView setPostsFrameChangedNotifications: NO]; + [m_contentView retain]; + if (m_contentView.superview) // m_contentView comes from another NSWindow + [m_contentView removeFromSuperview]; [window setContentView:m_contentView]; + [m_contentView release]; [m_contentView setPostsFrameChangedNotifications: YES]; } } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index d72664f0a0..73f8d276a8 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -594,6 +594,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; CGImageRelease(subMask); [self invalidateWindowShadowIfNeeded]; + + m_backingStore = 0; } - (BOOL) isFlipped diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index d1e3ae6a88..45856f3e6c 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -731,6 +731,9 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req) void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event) { QClipboard::Mode mode = modeForAtom(event->selection); + if (mode > QClipboard::Selection) + return; + // here we care only about the xfixes events that come from non Qt processes if (event->owner != XCB_NONE && event->owner != owner()) { if (!m_xClipboard[mode]) { diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 84e46a7339..90d323ed34 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -361,8 +361,10 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) QTouchDevice::Capabilities caps = 0; dev = new XInput2TouchDeviceData; dev->xiDeviceInfo = XIQueryDevice(static_cast<Display *>(m_xlib_display), id, &nrDevices); - if (nrDevices <= 0) + if (nrDevices <= 0) { + delete dev; return 0; + } int type = -1; int maxTouchPoints = 1; bool hasRelativeCoords = false; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 90479f39eb..7e70e7258d 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -848,8 +848,10 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const baseLayout, latchedLayout, lockedLayout); xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, event->nativeScanCode()); - if (sym == XKB_KEY_NoSymbol) + if (sym == XKB_KEY_NoSymbol) { + xkb_state_unref(kb_state); return QList<int>(); + } QList<int> result; int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode())); diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index e5f092b558..2bee9de1e8 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -211,6 +211,7 @@ bool Uic::write(QIODevice *in) #ifdef QT_UIC_JAVA_GENERATOR if (language.toLower() != QLatin1String("jambi")) { fprintf(stderr, "uic: File is not a 'jambi' form\n"); + delete ui; return false; } rtn = jwrite (ui); @@ -221,6 +222,7 @@ bool Uic::write(QIODevice *in) #ifdef QT_UIC_CPP_GENERATOR if (!language.isEmpty() && language.toLower() != QLatin1String("c++")) { fprintf(stderr, "uic: File is not a 'c++' ui file, language=%s\n", qPrintable(language)); + delete ui; return false; } diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index 9dba8ef894..0a4e57812a 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -1002,6 +1002,9 @@ void QTreeModel::timerEvent(QTimerEvent *ev) \since 4.2 Hides the item if \a hide is true, otherwise shows the item. + \note A call to this function has no effect if the item is not currently in a view. In particular, + calling \c setHidden(true) on an item and only then adding it to a view will result in + a visible item. \sa isHidden() */ diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index a98b2db0fc..3349b45467 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -271,7 +271,7 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge // (and reaches this point), then the menu item itself has been disabled. // This occurs at the QPA level on Mac, were we disable all the Cocoa menus // when showing a modal window. - if (a->shortcut().count() <= 1) + if (a->shortcut().count() < 1 || (a->shortcut().count() == 1 && (a->shortcut()[0] & Qt::MODIFIER_MASK) != 0)) continue; #endif QAction *a = menu->menuAction(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 423bb33cc2..de64755e4f 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -10528,6 +10528,22 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f) if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) { if (extra && extra->hasWindowContainer) QWindowContainer::toplevelAboutToBeDestroyed(q); + + QWindow *newParentWindow = newparent->windowHandle(); + if (!newParentWindow) + if (QWidget *npw = newparent->nativeParentWidget()) + newParentWindow = npw->windowHandle(); + + Q_FOREACH (QObject *child, q->windowHandle()->children()) { + QWindow *childWindow = qobject_cast<QWindow *>(child); + if (!childWindow) + continue; + + QWidgetWindow *childWW = qobject_cast<QWidgetWindow *>(childWindow); + QWidget *childWidget = childWW ? childWW->widget() : 0; + if (!childWW || (childWidget && childWidget->testAttribute(Qt::WA_NativeWindow))) + childWindow->setParent(newParentWindow); + } q->destroy(); } diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp index fe35c7c695..3916106af1 100644 --- a/src/widgets/styles/qgtkstyle.cpp +++ b/src/widgets/styles/qgtkstyle.cpp @@ -289,6 +289,7 @@ static QColor mergedColors(const QColor &colorA, const QColor &colorB, int facto static GdkColor fromQColor(const QColor &color) { GdkColor retval; + retval.pixel = 0; retval.red = color.red() * 255; retval.green = color.green() * 255; retval.blue = color.blue() * 255; diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index f0a45548f6..01a2f2b3bd 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1749,11 +1749,13 @@ ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags) return tds; } -NSView *QMacStylePrivate::buttonOfKind(ThemeButtonKind kind) const +NSView *QMacStylePrivate::buttonOfKind(ThemeButtonKind kind, QPoint *offset) const { NSView *bv = buttons[kind]; if (!bv) { - if (kind == kThemePopupButton) + if (kind == kThemePopupButton + || kind == kThemePopupButtonSmall + || kind == kThemePopupButtonMini) bv = [[NSPopUpButton alloc] init]; else if (kind == kThemeComboBox) bv = [[NSComboBox alloc] init]; @@ -1793,25 +1795,61 @@ NSView *QMacStylePrivate::buttonOfKind(ThemeButtonKind kind) const break; } -// if (kind == kThemePushButtonSmall -// || kind == kThemePopupButtonSmall -// || kind == kThemeCheckBoxSmall -// || kind == kThemeRadioButtonSmall) -// bc.controlSize = NSSmallControlSize; -// else if (kind == kThemePushButtonMini -// || kind == kThemePopupButtonMini -// || kind == kThemeCheckBoxMini -// || kind == kThemeRadioButtonMini) -// bc.controlSize = NSMiniControlSize; - if ([bv isKindOfClass:[NSButton class]]) { NSButton *bc = (NSButton *)bv; bc.title = nil; + + NSCell *bcell = bc.cell; + switch (kind) { + case kThemePushButtonSmall: + case kThemePopupButtonSmall: + case kThemeCheckBoxSmall: + case kThemeRadioButtonSmall: + bcell.controlSize = NSSmallControlSize; + break; + case kThemePushButtonMini: + case kThemePopupButtonMini: + case kThemeCheckBoxMini: + case kThemeRadioButtonMini: + bcell.controlSize = NSMiniControlSize; + break; + default: + break; + } } const_cast<QMacStylePrivate *>(this)->buttons.insert(kind, bv); } + if (offset) { + switch (kind) { + case kThemeRadioButton: + offset->setY(2); + break; + case kThemeRadioButtonSmall: + *offset = QPoint(-1, 2); + break; + case kThemeRadioButtonMini: + offset->setY(2); + break; + case kThemePopupButtonSmall: + case kThemeCheckBox: + offset->setY(1); + break; + case kThemeCheckBoxSmall: + offset->setX(-1); + break; + case kThemeCheckBoxMini: + *offset = QPoint(7, 5); + break; + case kThemePopupButtonMini: + *offset = QPoint(2, -1); + break; + default: + break; + } + } + return bv; } @@ -1827,8 +1865,8 @@ void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRect &qtRect, QPain CGRect rect = CGRectMake(qtRect.x() + 1, qtRect.y(), qtRect.width(), qtRect.height()); [backingStoreNSView addSubview:view]; - view.frame = rect; - [view drawRect:rect]; + view.frame = NSRectFromCGRect(rect); + [view drawRect:NSRectFromCGRect(rect)]; [view removeFromSuperviewWithoutNeedingDisplay]; [NSGraphicsContext restoreGraphicsState]; @@ -1928,14 +1966,20 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD } pm = QPixmap::fromImage(image); } else if ((usingYosemiteOrLater && combo && !editableCombo) || button) { - NSButton *bc = (NSButton *)buttonOfKind(bdi->kind); + QPoint offset; + NSButton *bc = (NSButton *)buttonOfKind(bdi->kind, &offset); [bc highlight:pressed]; bc.enabled = bdi->state != kThemeStateUnavailable && bdi->state != kThemeStateUnavailableInactive; + bc.allowsMixedState = YES; bc.state = bdi->value == kThemeButtonOn ? NSOnState : bdi->value == kThemeButtonMixed ? NSMixedState : NSOffState; - p->translate(0, 1); - drawNSViewInRect(bc, opt->rect, p); - p->translate(0, -1); + // The view frame may differ from what we pass to HITheme + QRect rect = opt->rect; + if (bdi->kind == kThemePopupButtonMini) + rect.adjust(0, 0, -5, 0); + p->translate(offset); + drawNSViewInRect(bc, rect, p); + p->translate(-offset); return; } else if (usingYosemiteOrLater && editableCombo) { QImage image = activePixmap.toImage(); @@ -3821,9 +3865,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter NSBezierPath *pushButtonFocusRingPath; if (bdi.kind == kThemeBevelButton) - pushButtonFocusRingPath = [NSBezierPath bezierPathWithRect:focusRect]; + pushButtonFocusRingPath = [NSBezierPath bezierPathWithRect:NSRectFromCGRect(focusRect)]; else - pushButtonFocusRingPath = [NSBezierPath bezierPathWithRoundedRect:focusRect xRadius:4 yRadius:4]; + pushButtonFocusRingPath = [NSBezierPath bezierPathWithRoundedRect:NSRectFromCGRect(focusRect) xRadius:4 yRadius:4]; qt_drawFocusRingOnPath(cg, pushButtonFocusRingPath); } diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index f5b67cd549..d145ff620b 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -187,7 +187,7 @@ public: void setAutoDefaultButton(QObject *button) const; - NSView *buttonOfKind(ThemeButtonKind kind) const; + NSView *buttonOfKind(ThemeButtonKind kind, QPoint *offset) const; void drawNSViewInRect(NSView *view, const QRect &rect, QPainter *p) const; void resolveCurrentNSView(QWindow *window); diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 422340747b..77a60997a6 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -120,6 +120,7 @@ private slots: void testEmptyData(); void testResourceFiles(); void testRegistryShortRootNames(); + void trailingWhitespace(); #ifdef Q_OS_MAC void fileName(); #endif @@ -2053,6 +2054,23 @@ void tst_QSettings::testRegistryShortRootNames() #endif } +void tst_QSettings::trailingWhitespace() +{ + { + QSettings s("tst_QSettings_trailingWhitespace"); + s.setValue("trailingSpace", "x "); + s.setValue("trailingTab", "x\t"); + s.setValue("trailingNewline", "x\n"); + } + { + QSettings s("tst_QSettings_trailingWhitespace"); + QCOMPARE(s.value("trailingSpace").toString(), QLatin1String("x ")); + QCOMPARE(s.value("trailingTab").toString(), QLatin1String("x\t")); + QCOMPARE(s.value("trailingNewline").toString(), QLatin1String("x\n")); + s.clear(); + } +} + void tst_QSettings::fromFile_data() { populateWithFormats(); diff --git a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp index aa63681664..4221097cd4 100644 --- a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp +++ b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp @@ -34,6 +34,7 @@ #include <QtTest/QtTest> #include <QtNetwork/QNetworkAccessManager> +#include <QtNetwork/QNetworkReply> #ifndef QT_NO_BEARERMANAGEMENT #include <QtNetwork/QNetworkConfigurationManager> #endif @@ -53,6 +54,7 @@ public: private slots: void networkAccessible(); + void alwaysCacheRequest(); }; tst_QNetworkAccessManager::tst_QNetworkAccessManager() @@ -118,5 +120,16 @@ void tst_QNetworkAccessManager::networkAccessible() #endif } +void tst_QNetworkAccessManager::alwaysCacheRequest() +{ + QNetworkAccessManager manager; + + QNetworkRequest req; + req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache); + QNetworkReply *reply = manager.get(req); + reply->close(); + delete reply; +} + QTEST_MAIN(tst_QNetworkAccessManager) #include "tst_qnetworkaccessmanager.moc" diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index ce1a4cee06..49cdeb71cf 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -7875,6 +7875,8 @@ protected slots: //qDebug() << Q_FUNC_INFO; bandwidthQuota = 8*1024; // fill quota emit readyRead(); + // Emitting readyRead() several times triggers a bug ("QIODevice::read: Called with maxSize < 0") we fix with this commit + emit readyRead(); } }; |