diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 6c7d60379ae..bdc6bd97dee 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1045,7 +1045,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM clearWinStatData(data); WIN32_FIND_DATA findData; // The memory structure for WIN32_FIND_DATA is same as WIN32_FILE_ATTRIBUTE_DATA - // for all members used by fillFindData(). + // for all members used by fillFindData(), except for dwReserved0. So we zero the + // whole struct to be extra safe. This also clears all internal FILETIME which for + // umounted drives has shown to be wrong. + ZeroMemory(&findData, sizeof(findData)); bool ok = ::GetFileAttributesEx((wchar_t*)fname.nativeFilePath().utf16(), GetFileExInfoStandard, reinterpret_cast(&findData)); if (ok) { diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 8ffc9879555..6c6996a0cdd 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -80,7 +80,7 @@ QColor qt_mac_toQColor(CGColorRef color); // Creates a mutable shape, it's the caller's responsibility to release. HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion); -OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); +void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 573140dec62..726d255ff6c 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -507,15 +507,8 @@ NSRect qt_mac_flipRect(const QRect &rect) return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height()); } -OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) +void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) { - // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev) - OSStatus err = noErr; - - require_action(inContext != NULL, InvalidContext, err = paramErr); - require_action(inBounds != NULL, InvalidBounds, err = paramErr); - require_action(inImage != NULL, InvalidImage, err = paramErr); - CGContextSaveGState( inContext ); CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds)); CGContextScaleCTM(inContext, 1, -1); @@ -523,10 +516,6 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm CGContextDrawImage(inContext, *inBounds, inImage); CGContextRestoreGState(inContext); -InvalidImage: -InvalidBounds: -InvalidContext: - return err; } Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index f661001687a..ce78cfdcdd3 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1574,10 +1574,16 @@ - (void)handleKeyEvent:(NSEvent *)nsevent eventType:(int)eventType QChar ch = QChar::ReplacementCharacter; int keyCode = Qt::Key_unknown; - if ([characters length] != 0) { + + // If a dead key occurs as a result of pressing a key combination then + // characters will have 0 length, but charactersIgnoringModifiers will + // have a valid character in it. This enables key combinations such as + // ALT+E to be used as a shortcut with an English keyboard even though + // pressing ALT+E will give a dead key while doing normal text input. + if ([characters length] != 0 || [charactersIgnoringModifiers length] != 0) { if (((modifiers & Qt::MetaModifier) || (modifiers & Qt::AltModifier)) && ([charactersIgnoringModifiers length] != 0)) ch = QChar([charactersIgnoringModifiers characterAtIndex:0]); - else + else if ([characters length] != 0) ch = QChar([characters characterAtIndex:0]); keyCode = [self convertKeyCode:ch]; } diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index b79341b8e43..283a73e9d63 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -91,13 +91,14 @@ class QTornOffMenu : public QMenu void setMenuSize(const QRect &screen) { Q_Q(QTornOffMenu); QSize size = q->sizeHint(); - if (scroll && (size.height() > screen.height() - titleBarHeight || size.width() > screen.width())) { + const int frameAddedHeight = q->frameGeometry().height() - q->geometry().height(); + if (scroll && (size.height() + frameAddedHeight > screen.height() || size.width() > screen.width())) { const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q); const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuHMargin, 0, q); scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown); size.setWidth(qMin(actionRects.at(getLastVisibleAction()).right() + fw + hmargin + rightmargin + 1, screen.width())); - size.setHeight(screen.height() - desktopFrame * 2 - titleBarHeight); + size.setHeight(screen.height() - desktopFrame * 2 - frameAddedHeight); } q->setFixedSize(size); } @@ -106,7 +107,6 @@ class QTornOffMenu : public QMenu QPointer causedMenu; QVector > causedStack; bool initialized; - int titleBarHeight; }; public: @@ -126,10 +126,6 @@ class QTornOffMenu : public QMenu if (style() != p->style()) setStyle(p->style()); - QStyleOption opt; - opt.init(this); - d->titleBarHeight = style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this); - int leftMargin, topMargin, rightMargin, bottomMargin; p->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin); @@ -292,7 +288,8 @@ int QMenuPrivate::scrollerHeight() const //Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't QRect QMenuPrivate::popupGeometry(const QWidget *widget) const { - if (QGuiApplicationPrivate::platformTheme() && + if ((widget->windowFlags() & Qt::Tool) != Qt::Tool && // Torn-off menus are different + QGuiApplicationPrivate::platformTheme() && QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::UseFullScreenForPopupMenu).toBool()) { return QApplication::desktop()->screenGeometry(widget); } else { @@ -359,11 +356,11 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const // Torn off menu windows should be adjusted by their frame height, otherwise some // window managers may behave unexpectedly if the window is taller than the screen. - int frameHeight = 0; + int frameAddedHeight = 0; if (!tearoff && (q->windowFlags() & Qt::WindowType_Mask) == Qt::Tool) - frameHeight = q->geometry().top() - q->frameGeometry().top(); + frameAddedHeight = q->frameGeometry().height() - q->geometry().height(); - const int column_max_y = screen.height() - 2 * deskFw - (vmargin + bottommargin + fw + frameHeight); + const int column_max_y = screen.height() - 2 * deskFw - (vmargin + bottommargin + fw + frameAddedHeight); int max_column_width = 0; int y = base_y; @@ -1289,7 +1286,10 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) if (e->type() == QEvent::MouseButtonRelease) { if (!tornPopup) tornPopup = new QTornOffMenu(q); - tornPopup->setGeometry(q->geometry()); + + // The torn-off menu should be of the right size. Make sure its titlebar is within the screen's bounds. + const auto frameOffset = tornPopup->geometry().topLeft() - tornPopup->frameGeometry().topLeft(); + tornPopup->setGeometry(q->geometry().translated(frameOffset)); tornPopup->show(); hideUpToMenuBar(); }