diff options
Diffstat (limited to 'src/plugins')
21 files changed, 274 insertions, 185 deletions
diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp index 9dbf7d7e0f..819ef6923f 100644 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ b/src/plugins/accessible/widgets/complexwidgets.cpp @@ -370,18 +370,6 @@ QStringList QAccessibleComboBox::keyBindingsForAction(const QString &/*actionNam #endif // QT_NO_COMBOBOX -static inline void removeInvisibleWidgetsFromList(QWidgetList *list) -{ - if (!list || list->isEmpty()) - return; - - for (int i = 0; i < list->count(); ++i) { - QWidget *widget = list->at(i); - if (!widget->isVisible()) - list->removeAt(i); - } -} - #ifndef QT_NO_SCROLLAREA // ======================= QAccessibleAbstractScrollArea ======================= QAccessibleAbstractScrollArea::QAccessibleAbstractScrollArea(QWidget *widget) diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index 03503ec632..8899d98795 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -220,6 +220,16 @@ QPlatformServices *QAndroidPlatformIntegration::services() const return m_androidPlatformServices; } +QVariant QAndroidPlatformIntegration::styleHint(StyleHint hint) const +{ + switch (hint) { + case ShowIsFullScreen: + return true; + default: + return QPlatformIntegration::styleHint(hint); + } +} + static const QLatin1String androidThemeName("android"); QStringList QAndroidPlatformIntegration::themeNames() const { diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h index 0e3a48c9f0..346d0c0953 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h @@ -113,6 +113,8 @@ public: QPlatformNativeInterface *nativeInterface() const; QPlatformServices *services() const; + QVariant styleHint(StyleHint hint) const; + QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h index e30f1d7425..59e029769d 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h @@ -59,15 +59,6 @@ public: void setCurrentColor(const QColor&); QColor currentColor() const; - -public: - bool showCocoaColorPanel(Qt::WindowModality windowModality, QWindow *parent); - bool hideCocoaColorPanel(); - - void createNSColorPanelDelegate(); - -private: - void *mDelegate; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index 13b4203f7f..d90d77ec1d 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -91,11 +91,14 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); @implementation QNSColorPanelDelegate -- (id)initWithDialogHelper:(QCocoaColorDialogHelper *)helper +- (id)init { self = [super init]; mColorPanel = [NSColorPanel sharedColorPanel]; - mHelper = helper; + mHelper = 0; + mStolenContentView = 0; + mOkButton = 0; + mCancelButton = 0; mResultCode = NSCancelButton; mDialogIsExecuting = false; mResultSet = false; @@ -105,11 +108,31 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); [mColorPanel setRestorable:NO]; #endif + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(colorChanged:) + name:NSColorPanelColorDidChangeNotification + object:mColorPanel]; + + [mColorPanel retain]; + return self; +} + +- (void)dealloc +{ + [self restoreOriginalContentView]; + [mColorPanel setDelegate:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} + +- (void)setDialogHelper:(QCocoaColorDialogHelper *)helper +{ + mHelper = helper; + [mColorPanel setShowsAlpha:mHelper->options()->testOption(QColorDialogOptions::ShowAlphaChannel)]; if (mHelper->options()->testOption(QColorDialogOptions::NoButtons)) { - mStolenContentView = 0; - mOkButton = 0; - mCancelButton = 0; - } else { + [self restoreOriginalContentView]; + } else if (!mStolenContentView) { // steal the color panel's contents view mStolenContentView = [mColorPanel contentView]; [mStolenContentView retain]; @@ -134,33 +157,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); [mCancelButton setAction:@selector(onCancelClicked)]; [mCancelButton setTarget:self]; } - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(colorChanged:) - name:NSColorPanelColorDidChangeNotification - object:mColorPanel]; - - [mColorPanel retain]; - return self; -} - -- (void)dealloc -{ - if (mOkButton) { - NSView *ourContentView = [mColorPanel contentView]; - - // return stolen stuff to its rightful owner - [mStolenContentView removeFromSuperview]; - [mColorPanel setContentView:mStolenContentView]; - [mOkButton release]; - [mCancelButton release]; - [ourContentView release]; - } - - [mColorPanel setDelegate:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [super dealloc]; } - (void)closePanel @@ -178,7 +174,25 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); { Q_UNUSED(notification); [self updateQtColor]; - emit mHelper->colorSelected(mQtColor); + if (mHelper) + emit mHelper->colorSelected(mQtColor); +} + +- (void)restoreOriginalContentView +{ + if (mStolenContentView) { + NSView *ourContentView = [mColorPanel contentView]; + + // return stolen stuff to its rightful owner + [mStolenContentView removeFromSuperview]; + [mColorPanel setContentView:mStolenContentView]; + [mOkButton release]; + [mCancelButton release]; + [ourContentView release]; + mOkButton = 0; + mCancelButton = 0; + mStolenContentView = 0; + } } - (void)relayout @@ -275,7 +289,8 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); mQtColor.setRgbF(red, green, blue, alpha); } } - emit mHelper->currentColorChanged(mQtColor); + if (mHelper) + emit mHelper->currentColorChanged(mQtColor); } - (void)showModelessPanel @@ -313,7 +328,8 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); [self finishOffWithCode:NSCancelButton]; } else { mResultSet = true; - emit mHelper->reject(); + if (mHelper) + emit mHelper->reject(); } return true; } @@ -348,27 +364,101 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); QT_BEGIN_NAMESPACE -QCocoaColorDialogHelper::QCocoaColorDialogHelper() : - mDelegate(0) +class QCocoaColorPanel +{ +public: + QCocoaColorPanel() + { + mDelegate = [[QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) alloc] init]; + } + + ~QCocoaColorPanel() + { + [mDelegate release]; + } + + void init(QCocoaColorDialogHelper *helper) + { + [mDelegate setDialogHelper:helper]; + } + + void cleanup(QCocoaColorDialogHelper *helper) + { + if (mDelegate->mHelper == helper) + mDelegate->mHelper = 0; + } + + bool exec() + { + // Note: If NSApp is not running (which is the case if e.g a top-most + // QEventLoop has been interrupted, and the second-most event loop has not + // yet been reactivated (regardless if [NSApp run] is still on the stack)), + // showing a native modal dialog will fail. + return [mDelegate runApplicationModalPanel]; + } + + bool show(Qt::WindowModality windowModality, QWindow *parent) + { + Q_UNUSED(parent); + if (windowModality != Qt::WindowModal) + [mDelegate showModelessPanel]; + // no need to show a Qt::WindowModal dialog here, because it's necessary to call exec() in that case + return true; + } + + void hide() + { + [mDelegate closePanel]; + } + + QColor currentColor() const + { + return mDelegate->mQtColor; + } + + void setCurrentColor(const QColor &color) + { + // make sure that if ShowAlphaChannel option is set then also setShowsAlpha + // needs to be set, otherwise alpha value is omitted + if (color.alpha() < 255) + [mDelegate->mColorPanel setShowsAlpha:YES]; + + NSColor *nsColor; + const QColor::Spec spec = color.spec(); + if (spec == QColor::Cmyk) { + nsColor = [NSColor colorWithDeviceCyan:color.cyanF() + magenta:color.magentaF() + yellow:color.yellowF() + black:color.blackF() + alpha:color.alphaF()]; + } else { + nsColor = [NSColor colorWithCalibratedRed:color.redF() + green:color.greenF() + blue:color.blueF() + alpha:color.alphaF()]; + } + mDelegate->mQtColor = color; + [mDelegate->mColorPanel setColor:nsColor]; + } + +private: + QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *mDelegate; +}; + +Q_GLOBAL_STATIC(QCocoaColorPanel, sharedColorPanel) + +QCocoaColorDialogHelper::QCocoaColorDialogHelper() { } QCocoaColorDialogHelper::~QCocoaColorDialogHelper() { - if (!mDelegate) - return; - [reinterpret_cast<QNSColorPanelDelegate *>(mDelegate) release]; - mDelegate = 0; + sharedColorPanel()->cleanup(this); } void QCocoaColorDialogHelper::exec() { - // Note: If NSApp is not running (which is the case if e.g a top-most - // QEventLoop has been interrupted, and the second-most event loop has not - // yet been reactivated (regardless if [NSApp run] is still on the stack)), - // showing a native modal dialog will fail. - QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate); - if ([delegate runApplicationModalPanel]) + if (sharedColorPanel()->exec()) emit accept(); else emit reject(); @@ -378,89 +468,24 @@ bool QCocoaColorDialogHelper::show(Qt::WindowFlags, Qt::WindowModality windowMod { if (windowModality == Qt::WindowModal) windowModality = Qt::ApplicationModal; - return showCocoaColorPanel(windowModality, parent); + sharedColorPanel()->init(this); + return sharedColorPanel()->show(windowModality, parent); } void QCocoaColorDialogHelper::hide() { - if (!mDelegate) - return; - QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate); - if (![delegate->mColorPanel isVisible]) - return; - if (delegate->mDialogIsExecuting) - [delegate->mColorPanel performClose:delegate]; - else - [delegate->mColorPanel close]; + sharedColorPanel()->hide(); } void QCocoaColorDialogHelper::setCurrentColor(const QColor &color) { - if (!mDelegate) - createNSColorPanelDelegate(); - QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate); - - // make sure that if ShowAlphaChannel option is set then also setShowsAlpha - // needs to be set, otherwise alpha value is omitted - [delegate->mColorPanel setShowsAlpha:options()->testOption(QColorDialogOptions::ShowAlphaChannel)]; - - NSColor *nsColor; - const QColor::Spec spec = color.spec(); - if (spec == QColor::Cmyk) { - nsColor = [NSColor colorWithDeviceCyan:color.cyanF() - magenta:color.magentaF() - yellow:color.yellowF() - black:color.blackF() - alpha:color.alphaF()]; - } else { - nsColor = [NSColor colorWithCalibratedRed:color.redF() - green:color.greenF() - blue:color.blueF() - alpha:color.alphaF()]; - } - delegate->mQtColor = color; - [delegate->mColorPanel setColor:nsColor]; + sharedColorPanel()->init(this); + sharedColorPanel()->setCurrentColor(color); } QColor QCocoaColorDialogHelper::currentColor() const { - if (!mDelegate) - return QColor(); - return reinterpret_cast<QNSColorPanelDelegate *>(mDelegate)->mQtColor; -} - -void QCocoaColorDialogHelper::createNSColorPanelDelegate() -{ - if (mDelegate) - return; - - QNSColorPanelDelegate *delegate = [[QNSColorPanelDelegate alloc] - initWithDialogHelper:this]; - - mDelegate = delegate; -} - -bool QCocoaColorDialogHelper::showCocoaColorPanel(Qt::WindowModality windowModality, QWindow *parent) -{ - Q_UNUSED(parent); - createNSColorPanelDelegate(); - QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate); - [delegate->mColorPanel setShowsAlpha:options()->testOption(QColorDialogOptions::ShowAlphaChannel)]; - if (windowModality != Qt::WindowModal) - [delegate showModelessPanel]; - // no need to show a Qt::WindowModal dialog here, because it's necessary to call exec() in that case - return true; -} - -bool QCocoaColorDialogHelper::hideCocoaColorPanel() -{ - if (!mDelegate){ - return false; - } else { - QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate); - [delegate closePanel]; - return true; - } + return sharedColorPanel()->currentColor(); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index c801d9d926..3e402673f3 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -71,6 +71,7 @@ inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qst CGImageRef qt_mac_image_to_cgimage(const QImage &image); NSImage *qt_mac_cgimage_to_nsimage(CGImageRef iamge); NSImage *qt_mac_create_nsimage(const QPixmap &pm); +NSImage *qt_mac_create_nsimage(const QIcon &icon); NSSize qt_mac_toNSSize(const QSize &qtSize); NSRect qt_mac_toNSRect(const QRect &rect); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 8ab1d9b579..3be294de7e 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -84,11 +84,8 @@ static void drawImageReleaseData (void *info, const void *, size_t) CGImageRef qt_mac_image_to_cgimage(const QImage &img) { - if (img.width() <= 0 || img.height() <= 0) { - qWarning() << Q_FUNC_INFO << - "trying to set" << img.width() << "x" << img.height() << "size for CGImage"; + if (img.isNull()) return 0; - } QImage *image; if (img.depth() != 32) @@ -124,16 +121,7 @@ CGImageRef qt_mac_image_to_cgimage(const QImage &img) NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image) { - QCocoaAutoReleasePool pool; - NSImage *newImage = 0; - NSRect imageRect = NSMakeRect(0.0, 0.0, CGImageGetWidth(image), CGImageGetHeight(image)); - newImage = [[NSImage alloc] initWithSize:imageRect.size]; - [newImage lockFocus]; - { - CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image); - } - [newImage unlockFocus]; + NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize]; return newImage; } @@ -148,6 +136,24 @@ NSImage *qt_mac_create_nsimage(const QPixmap &pm) return nsImage; } +NSImage *qt_mac_create_nsimage(const QIcon &icon) +{ + if (icon.isNull()) + return nil; + + NSImage *nsImage = [[NSImage alloc] init]; + foreach (QSize size, icon.availableSizes()) { + QPixmap pm = icon.pixmap(size); + QImage image = pm.toImage(); + CGImageRef cgImage = qt_mac_image_to_cgimage(image); + NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage]; + [nsImage addRepresentation:imageRep]; + [imageRep release]; + CGImageRelease(cgImage); + } + return nsImage; +} + HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion) { HIMutableShapeRef shape = HIShapeCreateMutable(); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index f6378d126f..8c4325a775 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -49,6 +49,7 @@ #include <QtGui/private/qguiapplication_p.h> #include "qcocoaapplication.h" #include "qcocoamenuloader.h" +#include "qcocoamenubar.h" #include "qcocoawindow.h" #import "qnsview.h" @@ -540,6 +541,7 @@ void QCocoaMenu::syncModalState(bool modal) void QCocoaMenu::setMenuBar(QCocoaMenuBar *menuBar) { m_menuBar = menuBar; + setParent(menuBar); } QCocoaMenuBar *QCocoaMenu::menuBar() const diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 52bfdfa385..da2704f19c 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -203,6 +203,11 @@ void QCocoaMenuBar::updateMenuBarImmediately() QCocoaAutoReleasePool pool; QCocoaMenuBar *mb = findGlobalMenubar(); QCocoaWindow *cw = findWindowForMenubar(); + + QWindow *win = cw ? cw->window() : 0; + if (win && (win->flags() & Qt::Popup) == Qt::Popup) + return; // context menus, comboboxes, etc. don't need to update the menubar + if (cw && cw->menubar()) mb = cw->menubar(); diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 4fb79f6c93..013f9931ff 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -310,7 +310,8 @@ NSMenuItem *QCocoaMenuItem::sync() } if (!m_icon.isNull()) { - NSImage *img = static_cast<NSImage *>(qt_mac_create_nsimage(m_icon.pixmap(16, QIcon::Normal))); + NSImage *img = qt_mac_create_nsimage(m_icon); + [img setSize:NSMakeSize(16, 16)]; [m_native setImage: img]; [img release]; } diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 5a5b2bc51f..1484ae2ba3 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -260,8 +260,9 @@ QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &siz return QPixmap(); NSRect iconRect = NSMakeRect(0, 0, size.width(), size.height()); + NSGraphicsContext *gc = [NSGraphicsContext currentContext]; CGImageRef cgImage = [iconImage CGImageForProposedRect:&iconRect - context:[NSGraphicsContext currentContext] + context:([gc graphicsPort] ? gc : nil) hints:nil]; QPixmap pixmap = QPixmap::fromImage(qt_mac_toQImage(cgImage)); return pixmap; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 70b08c7feb..288d4b4742 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -916,6 +916,7 @@ static QTouchDevice *touchDevice = 0; ulong timestamp = [nsevent timestamp] * 1000; ulong nativeModifiers = [nsevent modifierFlags]; Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers]; + NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers]; NSString *characters = [nsevent characters]; // There is no way to get the scan code from carbon/cocoa. But we cannot @@ -927,7 +928,10 @@ static QTouchDevice *touchDevice = 0; QChar ch = QChar::ReplacementCharacter; int keyCode = Qt::Key_unknown; if ([characters length] != 0) { - ch = QChar([characters characterAtIndex:0]); + if ((modifiers & Qt::MetaModifier) && ([charactersIgnoringModifiers length] != 0)) + ch = QChar([charactersIgnoringModifiers characterAtIndex:0]); + else + ch = QChar([characters characterAtIndex:0]); keyCode = [self convertKeyCode:ch]; } diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 07368f6ab6..85f560a722 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -190,8 +190,11 @@ void QIOSContext::windowDestroyed(QObject *object) { QWindow *window = static_cast<QWindow *>(object); if (m_framebufferObjects.contains(window)) { + EAGLContext *originalContext = [EAGLContext currentContext]; + [EAGLContext setCurrentContext:m_eaglContext]; deleteBuffers(m_framebufferObjects[window]); m_framebufferObjects.remove(window); + [EAGLContext setCurrentContext:originalContext]; } } diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index ce61a8b092..93592eb969 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -564,15 +564,10 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long if (!accessible) return E_FAIL; - QRect rect; - if (varID.lVal) { - QAccessibleInterface *child = accessible->child(varID.lVal - 1); - if (!child || !child->isValid()) - return E_FAIL; - rect = child->rect(); - } else { - rect = accessible->rect(); - } + QAccessibleInterface *acc = childPointer(accessible, varID); + if (!acc || !acc->isValid()) + return E_FAIL; + const QRect rect = acc->rect(); *pxLeft = rect.x(); *pyTop = rect.y(); diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 12dd00f104..33bed61398 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -2023,7 +2023,7 @@ void QWindowsNativeColorDialog::exec(HWND owner) qCustomColors[c] = COLORREFToQColor(m_customColors[c]).rgb(); emit accepted(); if (QWindowsContext::verboseDialogs) - qDebug() << '<' << __FUNCTION__ << m_color; + qDebug() << '<' << __FUNCTION__ << *m_color; } else { emit rejected(); } @@ -2044,7 +2044,7 @@ void QWindowsNativeColorDialog::exec(HWND owner) class QWindowsColorDialogHelper : public QWindowsDialogHelperBase<QPlatformColorDialogHelper> { public: - QWindowsColorDialogHelper() {} + QWindowsColorDialogHelper() : m_currentColor(new QColor) {} virtual bool supportsNonModalDialog() { return false; } @@ -2064,6 +2064,8 @@ QWindowsNativeDialogBase *QWindowsColorDialogHelper::createNativeDialog() { QWindowsNativeColorDialog *nativeDialog = new QWindowsNativeColorDialog(m_currentColor); nativeDialog->setWindowTitle(options()->windowTitle()); + connect(nativeDialog, SIGNAL(accepted()), this, SIGNAL(accept())); + connect(nativeDialog, SIGNAL(rejected()), this, SIGNAL(reject())); return nativeDialog; } #endif // USE_NATIVE_COLOR_DIALOG @@ -2096,9 +2098,9 @@ QPlatformDialogHelper *createHelper(QPlatformTheme::DialogType type) return 0; switch (type) { case QPlatformTheme::FileDialog: -#ifndef Q_OS_WINCE +#ifndef Q_OS_WINCE // Note: "Windows XP Professional x64 Edition has version number WV_5_2 (WV_2003). if (QWindowsIntegration::instance()->options() & QWindowsIntegration::XpNativeDialogs - || QSysInfo::windowsVersion() == QSysInfo::WV_XP) { + || QSysInfo::windowsVersion() <= QSysInfo::WV_2003) { return new QWindowsXpFileDialogHelper(); } if (QSysInfo::windowsVersion() > QSysInfo::WV_XP) diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index c6cfa4dbbc..43286eadf3 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -157,14 +157,19 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { - enum { signatureMask = 0xffffff00, miWpSignature = 0xff515700 }; +#ifdef Q_COMPILER_CLASS_ENUM + enum : quint64 { signatureMask = 0xffffff00, miWpSignature = 0xff515700 }; +#else + static const quint64 signatureMask = 0xffffff00; + static const quint64 miWpSignature = 0xff515700; +#endif // !Q_COMPILER_CLASS_ENUM if (et == QtWindows::MouseWheelEvent) return translateMouseWheelEvent(window, hwnd, msg, result); #ifndef Q_OS_WINCE // Check for events synthesized from touch. Lower byte is touch index, 0 means pen. - const LPARAM extraInfo = GetMessageExtraInfo(); + const quint64 extraInfo = GetMessageExtraInfo(); const bool fromTouch = (extraInfo & signatureMask) == miWpSignature && (extraInfo & 0xff); if (fromTouch) return false; diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index 250fea56b1..546957a043 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#define QT_NO_URL_CAST_FROM_STRING #include "qwindowsservices.h" #include "qtwindows_additional.h" @@ -55,19 +56,20 @@ QT_BEGIN_NAMESPACE enum { debug = 0 }; -static inline bool shellExecute(const QString &file) +static inline bool shellExecute(const QUrl &url) { #ifndef Q_OS_WINCE - const QString nativeFilePath = QDir::toNativeSeparators(file); + const QString nativeFilePath = + url.isLocalFile() ? QDir::toNativeSeparators(url.toLocalFile()) : url.toString(QUrl::FullyEncoded); const quintptr result = (quintptr)ShellExecute(0, 0, (wchar_t*)nativeFilePath.utf16(), 0, 0, SW_SHOWNORMAL); // ShellExecute returns a value greater than 32 if successful if (result <= 32) { - qWarning("ShellExecute '%s' failed (error %s).", qPrintable(file), qPrintable(QString::number(result))); + qWarning("ShellExecute '%s' failed (error %s).", qPrintable(url.toString()), qPrintable(QString::number(result))); return false; } return true; #else - Q_UNUSED(file) + Q_UNUSED(url); return false; #endif } @@ -131,7 +133,7 @@ static inline bool launchMail(const QUrl &url) } // Pass the url as the parameter. Should use QProcess::startDetached(), // but that cannot handle a Windows command line [yet]. - command.replace(QStringLiteral("%1"), url.toString()); + command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded)); if (debug) qDebug() << __FUNCTION__ << "Launching" << command; //start the process @@ -152,16 +154,14 @@ static inline bool launchMail(const QUrl &url) bool QWindowsServices::openUrl(const QUrl &url) { const QString scheme = url.scheme(); - if (scheme.isEmpty()) - return openDocument(url); if (scheme == QStringLiteral("mailto") && launchMail(url)) return true; - return shellExecute(QLatin1String(url.toEncoded())); + return shellExecute(url); } bool QWindowsServices::openDocument(const QUrl &url) { - return shellExecute(url.isLocalFile() ? url.toLocalFile() : url.toString()); + return shellExecute(url); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 08ff7123eb..c3ec949eef 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -845,7 +845,6 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : QWindowsWindow::~QWindowsWindow() { #ifndef Q_OS_WINCE - QWindowSystemInterface::flushWindowSystemEvents(); if (testFlag(TouchRegistered)) QWindowsContext::user32dll.unregisterTouchWindow(m_data.hwnd); #endif // !Q_OS_WINCE @@ -1390,9 +1389,22 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) setFlag(FrameDirty); m_windowState = state; QWindowSystemInterface::handleWindowStateChanged(window(), state); - if (state == Qt::WindowMinimized) { + switch (state) { + case Qt::WindowMinimized: handleHidden(); QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now. + break; + case Qt::WindowNoState: + // QTBUG-17548: We send expose events when receiving WM_Paint, but for + // layered windows, we won't receive any WM_Paint. + if (GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) { + fireExpose(QRegion(0, 0, window()->width(), window()->height())); + if (!QWindowsContext::instance()->asyncExpose()) + QWindowSystemInterface::flushWindowSystemEvents(); + } + break; + default: + break; } } diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 751bd168f6..5fbc23c049 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1043,6 +1043,10 @@ void QXcbKeyboard::updateVModMapping() vmod_masks.meta = bit; else if (qstrcmp(vmod_name, "AltGr") == 0) vmod_masks.altgr = bit; + else if (qstrcmp(vmod_name, "Super") == 0) + vmod_masks.super = bit; + else if (qstrcmp(vmod_name, "Hyper") == 0) + vmod_masks.hyper = bit; } free(name_reply); @@ -1104,9 +1108,14 @@ void QXcbKeyboard::updateVModToRModMapping() rmod_masks.meta = modmap; else if (vmod_masks.altgr == bit) rmod_masks.altgr = modmap; + else if (vmod_masks.super == bit) + rmod_masks.super = modmap; + else if (vmod_masks.hyper == bit) + rmod_masks.hyper = modmap; } free(map_reply); + resolveMaskConflicts(); } #else void QXcbKeyboard::updateModifiers() @@ -1131,7 +1140,8 @@ void QXcbKeyboard::updateModifiers() // for Alt and Meta L and R are the same static const xcb_keysym_t symbols[] = { - XK_Alt_L, XK_Meta_L, XK_Mode_switch + XK_Alt_L, XK_Meta_L, XK_Mode_switch, XK_Super_L, XK_Super_R, + XK_Hyper_L, XK_Hyper_R }; static const size_t numSymbols = sizeof symbols / sizeof *symbols; @@ -1157,6 +1167,10 @@ void QXcbKeyboard::updateModifiers() rmod_masks.meta = mask; if (sym == XK_Mode_switch) rmod_masks.altgr = mask; + if ((sym == XK_Super_L) || (sym == XK_Super_R)) + rmod_masks.super = mask; + if ((sym == XK_Hyper_L) || (sym == XK_Hyper_R)) + rmod_masks.hyper = mask; } } } @@ -1165,9 +1179,28 @@ void QXcbKeyboard::updateModifiers() for (size_t i = 0; i < numSymbols; ++i) free(modKeyCodes[i]); free(modMapReply); + resolveMaskConflicts(); } #endif +void QXcbKeyboard::resolveMaskConflicts() +{ + // if we don't have a meta key (or it's hidden behind alt), use super or hyper to generate + // Qt::Key_Meta and Qt::MetaModifier, since most newer XFree86/Xorg installations map the Windows + // key to Super + if (rmod_masks.alt == rmod_masks.meta) + rmod_masks.meta = 0; + + if (rmod_masks.meta == 0) { + // no meta keys... s/meta/super, + rmod_masks.meta = rmod_masks.super; + if (rmod_masks.meta == 0) { + // no super keys either? guess we'll use hyper then + rmod_masks.meta = rmod_masks.hyper; + } + } +} + class KeyChecker { public: diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index af6677c20f..770a7eabea 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -84,6 +84,7 @@ public: protected: void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time); + void resolveMaskConflicts(); QString keysymToUnicode(xcb_keysym_t sym) const; @@ -111,6 +112,8 @@ private: uint alt; uint altgr; uint meta; + uint super; + uint hyper; }; _mod_masks rmod_masks; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index b9a2b0d37b..3a19788316 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -239,7 +239,7 @@ void QXcbWindow::create() // XCB_CW_BACK_PIXMAP XCB_NONE, // XCB_CW_OVERRIDE_REDIRECT - type == Qt::Popup || type == Qt::ToolTip, + type == Qt::Popup || type == Qt::ToolTip || (window()->flags() & Qt::BypassWindowManagerHint), // XCB_CW_SAVE_UNDER type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer, // XCB_CW_EVENT_MASK |