diff options
Diffstat (limited to 'src/plugins')
29 files changed, 439 insertions, 243 deletions
diff --git a/src/plugins/platforms/README b/src/plugins/platforms/README new file mode 100644 index 0000000000..b44d04f58c --- /dev/null +++ b/src/plugins/platforms/README @@ -0,0 +1,49 @@ +The Qt Platform Abstraction - QPA + +QPA is the platform abstraction layer for Qt 5 and replaces QWS and the +platform ports from Qt 4. + +There is currently little documentation for QPA. The best approach for +developing a new platform plugin is to look at the other plugins and +see how they implement the APIs in question. The "minimal" plugin +is a good starting point. The xcb, windows, cocoa, and qnx plugins +are also actively developed and up to date. + +QPA plugins are implemented by subclassing various QPlatform* +classes. There are two "root" classes: QPlatformIntegration for +window system integration and QPlatformTheme for deeper platform +theming and integration. QStyle is not a part of QPA. + +The APIs provided by QPlatformIntegration are at this point (5.0 Alpha) +mostly stable. QPlatformTheme still has ongoing development. There +are no source or binary compatibility guarantees for the QPA classes, +meaning that a platform plugin is only guaranteed to work with the Qt +version it was developed against. API changes will however only be +made in minor releases. (5.1, 5.2, and so on.) + +Class Overview: + +QPlatformIntegration + QPlatformWindow + QPlatformBackingStore + QPlatformOpenGLContext + QPlatformSharedGraphicsCache + QPlatformFontDatabase + QPlatformClipboard + QPlatformDrag + QAbstractEventDispatcher + QPlatformInputContext + QPlatformAccessibility + QPlatformNativeInterface + QPlatformServices + +QPlatformTheme + QPlatformMenu + QPlatformMenuBar + QPlatformDialogHelper + platform palettes + platform fonts + theme hints + +src/platformsupport contains several helper classes for implementing +platform plugins on unix-like systems. diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index e861f48e7b..2ae39dd16c 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -73,7 +73,7 @@ HEADERS += qcocoaintegration.h \ FORMS += $$PWD/../../../widgets/dialogs/qfiledialog.ui RESOURCES += qcocoaresources.qrc -LIBS += -framework Cocoa +LIBS += -framework Cocoa -framework IOKit QT += core-private gui-private widgets-private platformsupport-private printsupport diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index bfc626fdba..fd4d6605a9 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -404,6 +404,11 @@ void QCocoaColorDialogHelper::setCurrentColor_sys(const QColor &color) if (!mDelegate) createNSColorPanelDelegate(); QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(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) { diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.h b/src/plugins/platforms/cocoa/qcocoainputcontext.h index 172c87e2dc..1fda29209d 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.h +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.h @@ -59,7 +59,8 @@ public: virtual void reset(); private Q_SLOTS: - void inputItemChanged(); + void connectSignals(); + void focusObjectChanged(QObject *focusObject); private: QPointer<QWindow> mWindow; diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm index db3488a0f5..5ac7f72acf 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm @@ -83,7 +83,7 @@ QCocoaInputContext::QCocoaInputContext() : QPlatformInputContext() , mWindow(QGuiApplication::focusWindow()) { - connect(qApp->inputMethod(), SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); + QMetaObject::invokeMethod(this, "connectSignals", Qt::QueuedConnection); } QCocoaInputContext::~QCocoaInputContext() @@ -114,7 +114,13 @@ void QCocoaInputContext::reset() } } -void QCocoaInputContext::inputItemChanged() +void QCocoaInputContext::connectSignals() +{ + connect(qApp, SIGNAL(focusObjectChanged(QObject*)), this, SLOT(focusObjectChanged(QObject*))); + focusObjectChanged(qApp->focusObject()); +} + +void QCocoaInputContext::focusObjectChanged(QObject *focusObject) { mWindow = QGuiApplication::focusWindow(); } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 97e7a7ffde..fb3ee3290e 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -61,6 +61,7 @@ public: ~QCocoaScreen(); QRect geometry() const { return m_geometry; } + QRect availableGeometry() const { return m_availableGeometry; } int depth() const { return m_depth; } QImage::Format format() const { return m_format; } QSizeF physicalSize() const { return m_physicalSize; } @@ -69,6 +70,7 @@ public: public: NSScreen *m_screen; QRect m_geometry; + QRect m_availableGeometry; int m_depth; QImage::Format m_format; QSizeF m_physicalSize; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index f5febd4a16..f91351ad46 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -69,8 +69,12 @@ QCocoaScreen::QCocoaScreen(int screenIndex) :QPlatformScreen() { m_screen = [[NSScreen screens] objectAtIndex:screenIndex]; - NSRect rect = [m_screen frame]; - m_geometry = QRect(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); + NSRect frameRect = [m_screen frame]; + m_geometry = QRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height); + NSRect visibleRect = [m_screen visibleFrame]; + m_availableGeometry = QRect(visibleRect.origin.x, + frameRect.size.height - (visibleRect.origin.y + visibleRect.size.height), // invert y + visibleRect.size.width, visibleRect.size.height); m_format = QImage::Format_RGB32; diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index c2f5df4d38..d02154b006 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -122,24 +122,25 @@ QPalette * qt_mac_createSystemPalette() palette->setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191)); // System palette initialization: - palette->setBrush( QPalette::Active, QPalette::Highlight, qt_mac_colorForTheme(kThemeBrushPrimaryHighlightColor) ); - palette->setBrush( QPalette::Inactive, QPalette::Highlight, qt_mac_colorForTheme(kThemeBrushSecondaryHighlightColor) ); + palette->setBrush(QPalette::Active, QPalette::Highlight, qt_mac_colorForTheme(kThemeBrushPrimaryHighlightColor)); + qc = qt_mac_colorForTheme(kThemeBrushSecondaryHighlightColor); + palette->setBrush(QPalette::Inactive, QPalette::Highlight, qc); + palette->setBrush(QPalette::Disabled, QPalette::Highlight, qc); - palette->setBrush( QPalette::Disabled, QPalette::Highlight, qt_mac_colorForTheme(kThemeBrushSecondaryHighlightColor) ); - palette->setBrush( QPalette::Active, QPalette::Shadow, qt_mac_colorForTheme(kThemeBrushButtonActiveDarkShadow) ); - - palette->setBrush( QPalette::Inactive, QPalette::Shadow, qt_mac_colorForTheme(kThemeBrushButtonInactiveDarkShadow) ); - palette->setBrush( QPalette::Disabled, QPalette::Shadow, qt_mac_colorForTheme(kThemeBrushButtonInactiveDarkShadow) ); + palette->setBrush(QPalette::Active, QPalette::Shadow, qt_mac_colorForTheme(kThemeBrushButtonActiveDarkShadow)); + qc = qt_mac_colorForTheme(kThemeBrushButtonInactiveDarkShadow); + palette->setBrush(QPalette::Inactive, QPalette::Shadow, qc); + palette->setBrush(QPalette::Disabled, QPalette::Shadow, qc); qc = qt_mac_colorForThemeTextColor(kThemeTextColorDialogActive); palette->setColor(QPalette::Active, QPalette::Text, qc); palette->setColor(QPalette::Active, QPalette::WindowText, qc); palette->setColor(QPalette::Active, QPalette::HighlightedText, qc); - - qc = qt_mac_colorForThemeTextColor(kThemeTextColorDialogInactive); palette->setColor(QPalette::Inactive, QPalette::Text, qc); palette->setColor(QPalette::Inactive, QPalette::WindowText, qc); palette->setColor(QPalette::Inactive, QPalette::HighlightedText, qc); + + qc = qt_mac_colorForThemeTextColor(kThemeTextColorDialogInactive); palette->setColor(QPalette::Disabled, QPalette::Text, qc); palette->setColor(QPalette::Disabled, QPalette::WindowText, qc); palette->setColor(QPalette::Disabled, QPalette::HighlightedText, qc); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 8bdb5535d5..90c5a050d0 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -92,6 +92,7 @@ public: ~QCocoaWindow(); void setGeometry(const QRect &rect); + void setCocoaGeometry(const QRect &rect); void setVisible(bool visible); Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); void setWindowTitle(const QString &title); @@ -110,6 +111,7 @@ public: void windowDidMove(); void windowDidResize(); void windowWillClose(); + bool windowIsPopupType() const; void setCurrentContext(QCocoaGLContext *context); QCocoaGLContext *currentContext() const; @@ -117,6 +119,7 @@ public: protected: // NSWindow handling. The QCocoaWindow/QNSView can either be displayed // in an existing NSWindow or in one created by Qt. + void recreateWindow(const QPlatformWindow *parentWindow); NSWindow *createNSWindow(); void setNSWindow(NSWindow *window); void clearNSWindow(NSWindow *window); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5c30e7f38b..b5e8ff2246 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -83,13 +83,19 @@ - (BOOL)canBecomeKeyWindow { - return NO; + // Most panels can be come the key window. Exceptions are: + if (m_cocoaPlatformWindow->window()->windowType() == Qt::ToolTip) + return NO; + if (m_cocoaPlatformWindow->window()->windowType() == Qt::SplashScreen) + return NO; + return YES; } @end QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) + , m_nsWindow(0) , m_glContext(0) , m_inConstructor(true) { @@ -98,8 +104,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) m_contentView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this]; setGeometry(tlw->geometry()); - m_nsWindow = createNSWindow(); - setNSWindow(m_nsWindow); + recreateWindow(parent()); m_inConstructor = false; } @@ -119,10 +124,18 @@ void QCocoaWindow::setGeometry(const QRect &rect) qDebug() << "QCocoaWindow::setGeometry" << this << rect; #endif QPlatformWindow::setGeometry(rect); + setCocoaGeometry(rect); +} - NSRect bounds = qt_mac_flipRect(rect, window()); - [m_nsWindow setContentSize : bounds.size]; - [m_nsWindow setFrameOrigin : bounds.origin]; +void QCocoaWindow::setCocoaGeometry(const QRect &rect) +{ + if (m_nsWindow) { + NSRect bounds = qt_mac_flipRect(rect, window()); + [m_nsWindow setContentSize : bounds.size]; + [m_nsWindow setFrameOrigin : bounds.origin]; + } else { + [m_contentView setFrame : NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; + } } void QCocoaWindow::setVisible(bool visible) @@ -151,13 +164,16 @@ void QCocoaWindow::setVisible(bool visible) // Make sure the QWindow has a frame ready before we show the NSWindow. QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); - if ([m_nsWindow canBecomeKeyWindow]) - [m_nsWindow makeKeyAndOrderFront:nil]; - else - [m_nsWindow orderFront: nil]; + if (m_nsWindow) { + if ([m_nsWindow canBecomeKeyWindow]) + [m_nsWindow makeKeyAndOrderFront:nil]; + else + [m_nsWindow orderFront: nil]; + } } else { // qDebug() << "close" << this; - [m_nsWindow orderOut:m_nsWindow]; + if (m_nsWindow) + [m_nsWindow orderOut:m_nsWindow]; } } @@ -170,6 +186,8 @@ Qt::WindowFlags QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) void QCocoaWindow::setWindowTitle(const QString &title) { QCocoaAutoReleasePool pool; + if (!m_nsWindow) + return; CFStringRef windowTitle = QCFString::toCFStringRef(title); [m_nsWindow setTitle: const_cast<NSString *>(reinterpret_cast<const NSString *>(windowTitle))]; @@ -180,17 +198,21 @@ void QCocoaWindow::raise() { //qDebug() << "raise" << this; // ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm) - [m_nsWindow orderFront: m_nsWindow]; + if (m_nsWindow) + [m_nsWindow orderFront: m_nsWindow]; } void QCocoaWindow::lower() { - [m_nsWindow orderBack: m_nsWindow]; + if (m_nsWindow) + [m_nsWindow orderBack: m_nsWindow]; } void QCocoaWindow::propagateSizeHints() { QCocoaAutoReleasePool pool; + if (!m_nsWindow) + return; [m_nsWindow setMinSize : qt_mac_toNSSize(window()->minimumSize())]; [m_nsWindow setMaxSize : qt_mac_toNSSize(window()->maximumSize())]; @@ -213,6 +235,9 @@ void QCocoaWindow::propagateSizeHints() bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) { + if (!m_nsWindow) + return false; + if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; else if (!grab && [m_nsWindow isKeyWindow]) @@ -222,6 +247,9 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) bool QCocoaWindow::setMouseGrabEnabled(bool grab) { + if (!m_nsWindow) + return false; + if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; else if (!grab && [m_nsWindow isKeyWindow]) @@ -231,23 +259,19 @@ bool QCocoaWindow::setMouseGrabEnabled(bool grab) WId QCocoaWindow::winId() const { - return WId(m_nsWindow); + return WId(m_contentView); } -void QCocoaWindow::setParent(const QPlatformWindow *window) +void QCocoaWindow::setParent(const QPlatformWindow *parentWindow) { // recreate the window for compatibility - clearNSWindow(m_nsWindow); - [m_nsWindow close]; - [m_nsWindow release]; - - m_nsWindow = createNSWindow(); - setNSWindow(m_nsWindow); + recreateWindow(parentWindow); + setCocoaGeometry(geometry()); } NSView *QCocoaWindow::contentView() const { - return [m_nsWindow contentView]; + return m_contentView; } void QCocoaWindow::windowWillMove() @@ -266,6 +290,9 @@ void QCocoaWindow::windowDidMove() void QCocoaWindow::windowDidResize() { + if (!m_nsWindow) + return; + NSRect rect = [[m_nsWindow contentView]frame]; // Call setFrameSize which will trigger a frameDidChangeNotification on QNSView. [[m_nsWindow contentView] setFrameSize:rect.size]; @@ -276,6 +303,15 @@ void QCocoaWindow::windowWillClose() QWindowSystemInterface::handleSynchronousCloseEvent(window()); } +bool QCocoaWindow::windowIsPopupType() const +{ + Qt::WindowType type = window()->windowType(); + if (type == Qt::Tool) + return false; // Qt::Tool has the Popup bit set but isn't, at least on Mac. + + return ((type & Qt::Popup) == Qt::Popup); +} + void QCocoaWindow::setCurrentContext(QCocoaGLContext *context) { m_glContext = context; @@ -286,6 +322,27 @@ QCocoaGLContext *QCocoaWindow::currentContext() const return m_glContext; } +void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) +{ + // Remove current window (if any) + if (m_nsWindow) { + clearNSWindow(m_nsWindow); + [m_nsWindow close]; + [m_nsWindow release]; + m_nsWindow = 0; + } + + if (!parentWindow) { + // Create a new NSWindow if this is a top-level window. + m_nsWindow = createNSWindow(); + setNSWindow(m_nsWindow); + } else { + // Child windows have no NSWindow, link the NSViews instead. + const QCocoaWindow *parentCococaWindow = static_cast<const QCocoaWindow *>(parentWindow); + [parentCococaWindow->m_contentView addSubview : m_contentView]; + } +} + NSWindow * QCocoaWindow::createNSWindow() { QCocoaAutoReleasePool pool; @@ -300,7 +357,7 @@ NSWindow * QCocoaWindow::createNSWindow() // Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen) if ((type & Qt::Popup) == Qt::Popup) { - if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::SplashScreen) { + if (windowIsPopupType()) { styleMask = NSBorderlessWindowMask; } else { styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | @@ -314,6 +371,7 @@ NSWindow * QCocoaWindow::createNSWindow() defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up // before the window is shown and needs a proper window.). [window setHasShadow:YES]; + window->m_cocoaPlatformWindow = this; createdWindow = window; } else { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); @@ -324,6 +382,15 @@ NSWindow * QCocoaWindow::createNSWindow() defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up // before the window is shown and needs a proper window.). window->m_cocoaPlatformWindow = this; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { + // All windows with the WindowMaximizeButtonHint set also get a full-screen button. + if (flags & Qt::WindowMaximizeButtonHint) + [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } +#endif + createdWindow = window; } return createdWindow; @@ -378,6 +445,9 @@ void QCocoaWindow::clearNSWindow(NSWindow *window) // Returns the current global screen geometry for the nswindow associated with this window. QRect QCocoaWindow::windowGeometry() const { + if (!m_nsWindow) + return geometry(); + NSRect rect = [m_nsWindow frame]; QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window()); int flippedY = onScreen->geometry().height() - rect.origin.y - rect.size.height; // account for nswindow inverted y. diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index f09c9331f6..2b7caae688 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -61,6 +61,7 @@ QT_END_NAMESPACE QString m_composingText; bool m_keyEventsAccepted; QStringList *currentCustomDragTypes; + Qt::KeyboardModifiers currentWheelModifiers; } - (id)init; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 3a697a3602..d249158db3 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -146,24 +146,24 @@ static QTouchDevice *touchDevice = 0; - (void)windowDidBecomeKey { -// QWindowSystemInterface::handleWindowActivated(m_window); + if (!m_platformWindow->windowIsPopupType()) + QWindowSystemInterface::handleWindowActivated(m_window); } - (void)windowDidResignKey { -// QWindowSystemInterface::handleWindowActivated(0); + if (!m_platformWindow->windowIsPopupType()) + QWindowSystemInterface::handleWindowActivated(0); } - (void)windowDidBecomeMain { // qDebug() << "window did become main" << m_window; - QWindowSystemInterface::handleWindowActivated(m_window); } - (void)windowDidResignMain { // qDebug() << "window did resign main" << m_window; - QWindowSystemInterface::handleWindowActivated(0); } @@ -304,7 +304,7 @@ static QTouchDevice *touchDevice = 0; - (void)mouseDragged:(NSEvent *)theEvent { if (!(m_buttons & Qt::LeftButton)) - qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); + qWarning("QNSView mouseDragged: Internal mouse button tracking invalid (missing Qt::LeftButton)"); [self handleMouseEvent:theEvent]; } @@ -339,8 +339,8 @@ static QTouchDevice *touchDevice = 0; - (void)rightMouseDragged:(NSEvent *)theEvent { - if (!(m_buttons & Qt::LeftButton)) - qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); + if (!(m_buttons & Qt::RightButton)) + qWarning("QNSView rightMouseDragged: Internal mouse button tracking invalid (missing Qt::RightButton)"); [self handleMouseEvent:theEvent]; } @@ -404,8 +404,8 @@ static QTouchDevice *touchDevice = 0; - (void)otherMouseDragged:(NSEvent *)theEvent { - if (!(m_buttons & Qt::LeftButton)) - qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); + if (!(m_buttons & ~(Qt::LeftButton | Qt::RightButton))) + qWarning("QNSView otherMouseDragged: Internal mouse button tracking invalid (missing Qt::MiddleButton or Qt::ExtraButton*)"); [self handleMouseEvent:theEvent]; } @@ -545,7 +545,31 @@ static QTouchDevice *touchDevice = 0; NSTimeInterval timestamp = [theEvent timestamp]; ulong qt_timestamp = timestamp * 1000; - QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, pixelDelta, angleDelta); + // Set keyboard modifiers depending on event phase. A two-finger trackpad flick + // generates a stream of scroll events. We want the keyboard modifier state to + // be the state at the beginning of the flick in order to avoid changing the + // interpretation of the events mid-stream. One example of this happening would + // be when pressing cmd after scrolling in Qt Creator: not taking the phase into + // account causes the end of the event stream to be interpreted as font size changes. + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) { + NSEventPhase phase = [theEvent phase]; + if (phase == NSEventPhaseBegan) { + currentWheelModifiers = [self convertKeyModifiers:[theEvent modifierFlags]]; + } + + QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, pixelDelta, angleDelta, currentWheelModifiers); + + if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) { + currentWheelModifiers = Qt::NoModifier; + } + } +#else + QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, pixelDelta, angleDelta, + [self convertKeyModifiers:[theEvent modifierFlags]]); +#endif + } #endif //QT_NO_WHEELEVENT @@ -590,10 +614,11 @@ static QTouchDevice *touchDevice = 0; QObject *fo = QGuiApplication::focusObject(); if (!m_keyEventsAccepted && fo) { - QInputMethodQueryEvent queryEvent(Qt::ImHints); + QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints); if (QCoreApplication::sendEvent(fo, &queryEvent)) { + bool imEnabled = queryEvent.value(Qt::ImEnabled).toBool(); Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt()); - if (!(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) + if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) [self interpretKeyEvents:[NSArray arrayWithObject:nsevent]]; } } @@ -630,10 +655,15 @@ static QTouchDevice *touchDevice = 0; } QObject *fo = QGuiApplication::focusObject(); if (fo) { - QInputMethodEvent e; - e.setCommitString(commitString); - QCoreApplication::sendEvent(fo, &e); - m_keyEventsAccepted = true; + QInputMethodQueryEvent queryEvent(Qt::ImEnabled); + if (QCoreApplication::sendEvent(fo, &queryEvent)) { + if (queryEvent.value(Qt::ImEnabled).toBool()) { + QInputMethodEvent e; + e.setCommitString(commitString); + QCoreApplication::sendEvent(fo, &e); + m_keyEventsAccepted = true; + } + } } m_composingText.clear(); @@ -691,9 +721,14 @@ static QTouchDevice *touchDevice = 0; QObject *fo = QGuiApplication::focusObject(); if (fo) { - QInputMethodEvent e(preeditString, attrs); - QCoreApplication::sendEvent(fo, &e); - m_keyEventsAccepted = true; + QInputMethodQueryEvent queryEvent(Qt::ImEnabled); + if (QCoreApplication::sendEvent(fo, &queryEvent)) { + if (queryEvent.value(Qt::ImEnabled).toBool()) { + QInputMethodEvent e(preeditString, attrs); + QCoreApplication::sendEvent(fo, &e); + m_keyEventsAccepted = true; + } + } } } @@ -702,9 +737,14 @@ static QTouchDevice *touchDevice = 0; if (!m_composingText.isEmpty()) { QObject *fo = QGuiApplication::focusObject(); if (fo) { - QInputMethodEvent e; - e.setCommitString(m_composingText); - QCoreApplication::sendEvent(fo, &e); + QInputMethodQueryEvent queryEvent(Qt::ImEnabled); + if (QCoreApplication::sendEvent(fo, &queryEvent)) { + if (queryEvent.value(Qt::ImEnabled).toBool()) { + QInputMethodEvent e; + e.setCommitString(m_composingText); + QCoreApplication::sendEvent(fo, &e); + } + } } } m_composingText.clear(); @@ -725,9 +765,11 @@ static QTouchDevice *touchDevice = 0; QObject *fo = QGuiApplication::focusObject(); if (!fo) return nil; - QInputMethodQueryEvent queryEvent(Qt::ImCurrentSelection); + QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection); if (!QCoreApplication::sendEvent(fo, &queryEvent)) return nil; + if (!queryEvent.value(Qt::ImEnabled).toBool()) + return nil; QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString(); if (selectedText.isEmpty()) @@ -761,9 +803,12 @@ static QTouchDevice *touchDevice = 0; QObject *fo = QGuiApplication::focusObject(); if (!fo) return selRange; - QInputMethodQueryEvent queryEvent(Qt::ImCurrentSelection); + QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection); if (!QCoreApplication::sendEvent(fo, &queryEvent)) return selRange; + if (!queryEvent.value(Qt::ImEnabled).toBool()) + return selRange; + QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString(); if (!selectedText.isEmpty()) { @@ -780,6 +825,12 @@ static QTouchDevice *touchDevice = 0; if (!fo) return NSZeroRect; + QInputMethodQueryEvent queryEvent(Qt::ImEnabled); + if (!QCoreApplication::sendEvent(fo, &queryEvent)) + return NSZeroRect; + if (!queryEvent.value(Qt::ImEnabled).toBool()) + return NSZeroRect; + if (!m_window) return NSZeroRect; @@ -804,10 +855,19 @@ static QTouchDevice *touchDevice = 0; - (NSArray*) validAttributesForMarkedText { + if (m_window != QGuiApplication::focusWindow()) + return nil; + QObject *fo = QGuiApplication::focusObject(); if (!fo) return nil; + QInputMethodQueryEvent queryEvent(Qt::ImEnabled); + if (!QCoreApplication::sendEvent(fo, &queryEvent)) + return nil; + if (!queryEvent.value(Qt::ImEnabled).toBool()) + return nil; + // Support only underline color/style. return [NSArray arrayWithObjects:NSUnderlineColorAttributeName, NSUnderlineStyleAttributeName, nil]; diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 8b8445c995..87f3713920 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -73,8 +73,6 @@ QT_BEGIN_NAMESPACE -extern int qt_antialiasing_threshold; // from qcoretextfontdatabase.mm - /***************************************************************************** QCoreGraphicsPaintEngine utility functions *****************************************************************************/ @@ -1182,7 +1180,9 @@ void QCoreGraphicsPaintEngine::drawTextItem(const QPointF &pos, const QTextItem QFontEngine *fe = ti.fontEngine; - const bool textAA = state->renderHints() & QPainter::TextAntialiasing && fe->fontDef.pointSize > qt_antialiasing_threshold && !(fe->fontDef.styleStrategy & QFont::NoAntialias); + const bool textAA = ((state->renderHints() & QPainter::TextAntialiasing) + && (fe->fontDef.pointSize > QCoreTextFontEngine::antialiasingThreshold) + && !(fe->fontDef.styleStrategy & QFont::NoAntialias)); const bool lineAA = state->renderHints() & QPainter::Antialiasing; if (textAA != lineAA) CGContextSetShouldAntialias(d->hd, textAA); diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index ed8503b53c..86a1b8239c 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -13,6 +13,9 @@ DESTDIR = $$QT.gui.plugins/platforms #DEFINES += Q_OPENKODE +#Avoid X11 header collision +DEFINES += MESA_EGL_NO_X11_HEADERS + SOURCES = main.cpp \ qeglfsintegration.cpp \ qeglfswindow.cpp \ @@ -24,7 +27,7 @@ HEADERS = qeglfsintegration.h \ qeglfsbackingstore.h \ qeglfsscreen.h -CONFIG += qpa/genericunixfontdatabase +CONFIG += egl qpa/genericunixfontdatabase target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.cpp b/src/plugins/platforms/openkode/qopenkodeintegration.cpp index d34bd8e029..705f332826 100644 --- a/src/plugins/platforms/openkode/qopenkodeintegration.cpp +++ b/src/plugins/platforms/openkode/qopenkodeintegration.cpp @@ -149,7 +149,7 @@ QOpenKODEIntegration::QOpenKODEIntegration() return; } if (displayNameLength) - delete displayName; + delete[] displayName; KDchar *desktopName = 0; KDsize desktopNameLength = 0; diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index c97c1def0c..692332291c 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -15,3 +15,7 @@ win32: SUBDIRS += windows qnx-*-qcc { SUBDIRS += qnx } + +contains(QT_CONFIG, eglfs) { + SUBDIRS += eglfs +} diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 1bd3548b7d..cf82084de0 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -16,7 +16,7 @@ QT += opengl opengl-private platformsupport platformsupport-private widgets-priv #DEFINES += QQNXINPUTCONTEXT_DEBUG #DEFINES += QQNXINPUTCONTEXT_IMF_EVENT_DEBUG #DEFINES += QQNXINTEGRATION_DEBUG -#DEFINES += QQNXNAVIGATORTHREAD_DEBUG +#DEFINES += QQNXNAVIGATOREVENTHANDLER_DEBUG #DEFINES += QQNXRASTERBACKINGSTORE_DEBUG #DEFINES += QQNXROOTWINDOW_DEBUG #DEFINES += QQNXSCREEN_DEBUG @@ -29,7 +29,7 @@ SOURCES = main.cpp \ qqnxglcontext.cpp \ qqnxglbackingstore.cpp \ qqnxintegration.cpp \ - qqnxnavigatorthread.cpp \ + qqnxnavigatoreventhandler.cpp \ qqnxscreen.cpp \ qqnxwindow.cpp \ qqnxrasterbackingstore.cpp \ @@ -41,7 +41,7 @@ HEADERS = qqnxbuffer.h \ qqnxeventthread.h \ qqnxkeytranslator.h \ qqnxintegration.h \ - qqnxnavigatorthread.h \ + qqnxnavigatoreventhandler.h \ qqnxglcontext.h \ qqnxglbackingstore.h \ qqnxscreen.h \ diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 2811661269..cb7f14f963 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -43,7 +43,7 @@ #include "qqnxeventthread.h" #include "qqnxglbackingstore.h" #include "qqnxglcontext.h" -#include "qqnxnavigatorthread.h" +#include "qqnxnavigatoreventhandler.h" #include "qqnxrasterbackingstore.h" #include "qqnxscreen.h" #include "qqnxwindow.h" @@ -77,7 +77,7 @@ QMutex QQnxIntegration::ms_windowMapperMutex; QQnxIntegration::QQnxIntegration() : QPlatformIntegration() , m_eventThread(0) - , m_navigatorThread(0) + , m_navigatorEventHandler(0) , m_inputContext(0) , m_fontDatabase(new QGenericUnixFontDatabase()) , m_paintUsingOpenGL(false) @@ -109,9 +109,15 @@ QQnxIntegration::QQnxIntegration() m_eventThread = new QQnxEventThread(m_screenContext, *QQnxScreen::primaryDisplay()); m_eventThread->start(); - // Create/start navigator thread - m_navigatorThread = new QQnxNavigatorThread(*QQnxScreen::primaryDisplay()); - m_navigatorThread->start(); + // Create/start navigator event handler + // Not on BlackBerry, it has specialised event dispatcher which also handles navigator events +#ifndef Q_OS_BLACKBERRY + m_navigatorEventHandler = new QQnxNavigatorEventHandler(*QQnxScreen::primaryDisplay()); + + // delay invocation of start() to the time the event loop is up and running + // needed to have the QThread internals of the main thread properly initialized + QMetaObject::invokeMethod(m_navigatorEventHandler, "start", Qt::QueuedConnection); +#endif // Create/start the keyboard class. QQnxVirtualKeyboard::instance(); @@ -137,7 +143,7 @@ QQnxIntegration::~QQnxIntegration() delete m_eventThread; // Stop/destroy navigator thread - delete m_navigatorThread; + delete m_navigatorEventHandler; // Destroy all displays QQnxScreen::destroyDisplays(); diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index 51d06bd0e6..892bb6e16f 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QQnxEventThread; class QQnxInputContext; -class QQnxNavigatorThread; +class QQnxNavigatorEventHandler; class QQnxWindow; #ifndef QT_NO_CLIPBOARD @@ -99,7 +99,7 @@ private: screen_context_t m_screenContext; QQnxEventThread *m_eventThread; - QQnxNavigatorThread *m_navigatorThread; + QQnxNavigatorEventHandler *m_navigatorEventHandler; QQnxInputContext *m_inputContext; QPlatformFontDatabase *m_fontDatabase; bool m_paintUsingOpenGL; diff --git a/src/plugins/platforms/qnx/qqnxnavigatorthread.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp index def4cb7eb1..4db86cb5cf 100644 --- a/src/plugins/platforms/qnx/qqnxnavigatorthread.cpp +++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qqnxnavigatorthread.h" +#include "qqnxnavigatoreventhandler.h" #include "qqnxscreen.h" #include <QtGui/QGuiApplication> @@ -61,25 +61,30 @@ static const char *navigatorControlPath = "/pps/services/navigator/control"; static const int ppsBufferSize = 4096; -QQnxNavigatorThread::QQnxNavigatorThread(QQnxScreen& primaryScreen) +QQnxNavigatorEventHandler::QQnxNavigatorEventHandler(QQnxScreen& primaryScreen) : m_primaryScreen(primaryScreen), m_fd(-1), m_readNotifier(0) { } -QQnxNavigatorThread::~QQnxNavigatorThread() +QQnxNavigatorEventHandler::~QQnxNavigatorEventHandler() { - // block until thread terminates - shutdown(); - delete m_readNotifier; + + // close connection to navigator + if (m_fd != -1) + close(m_fd); + +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) + qDebug() << "QQNX: navigator event handler stopped"; +#endif } -void QQnxNavigatorThread::run() +void QQnxNavigatorEventHandler::start() { -#if defined(QQNXNAVIGATORTHREAD_DEBUG) - qDebug() << "QQNX: navigator thread started"; +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) + qDebug() << "QQNX: navigator event handler started"; #endif // open connection to navigator @@ -91,39 +96,12 @@ void QQnxNavigatorThread::run() } m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read); - // using direct connection to get the slot called in this thread's context - connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(readData()), Qt::DirectConnection); - - exec(); - - // close connection to navigator - close(m_fd); - -#if defined(QQNXNAVIGATORTHREAD_DEBUG) - qDebug() << "QQNX: navigator thread stopped"; -#endif -} - -void QQnxNavigatorThread::shutdown() -{ -#if defined(QQNXNAVIGATORTHREAD_DEBUG) - qDebug() << "QQNX: navigator thread shutdown begin"; -#endif - - // signal thread to terminate - quit(); - - // block until thread terminates - wait(); - -#if defined(QQNXNAVIGATORTHREAD_DEBUG) - qDebug() << "QQNX: navigator thread shutdown end"; -#endif + connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(readData())); } -void QQnxNavigatorThread::parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id) +void QQnxNavigatorEventHandler::parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id) { -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: data=" << ppsData; #endif @@ -141,7 +119,7 @@ void QQnxNavigatorThread::parsePPS(const QByteArray &ppsData, QByteArray &msg, Q // tokenize current attribute const QByteArray &attr = lines.at(i); -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: attr=" << attr; #endif @@ -160,7 +138,7 @@ void QQnxNavigatorThread::parsePPS(const QByteArray &ppsData, QByteArray &msg, Q QByteArray key = attr.left(firstColon); QByteArray value = attr.mid(secondColon + 1); -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: key=" << key; qDebug() << "PPS: val=" << value; #endif @@ -178,7 +156,7 @@ void QQnxNavigatorThread::parsePPS(const QByteArray &ppsData, QByteArray &msg, Q } } -void QQnxNavigatorThread::replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat) +void QQnxNavigatorEventHandler::replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat) { // construct pps message QByteArray ppsData = "res::"; @@ -191,7 +169,7 @@ void QQnxNavigatorThread::replyPPS(const QByteArray &res, const QByteArray &id, } ppsData += "\n"; -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS reply=" << ppsData; #endif @@ -203,9 +181,9 @@ void QQnxNavigatorThread::replyPPS(const QByteArray &res, const QByteArray &id, } } -void QQnxNavigatorThread::handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id) +void QQnxNavigatorEventHandler::handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id) { -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: msg=" << msg << ", dat=" << dat << ", id=" << id; #endif @@ -213,7 +191,7 @@ void QQnxNavigatorThread::handleMessage(const QByteArray &msg, const QByteArray if (msg == "orientationCheck") { // reply to navigator that (any) orientation is acceptable -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: orientation check, o=" << dat; #endif replyPPS(msg, id, "true"); @@ -221,7 +199,7 @@ void QQnxNavigatorThread::handleMessage(const QByteArray &msg, const QByteArray } else if (msg == "orientation") { // update screen geometry and reply to navigator that we're ready -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: orientation, o=" << dat; #endif m_primaryScreen.setRotation( dat.toInt() ); @@ -231,7 +209,7 @@ void QQnxNavigatorThread::handleMessage(const QByteArray &msg, const QByteArray } else if (msg == "SWIPE_DOWN") { // simulate menu key press -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: menu"; #endif QWindow *w = QGuiApplication::focusWindow(); @@ -241,16 +219,16 @@ void QQnxNavigatorThread::handleMessage(const QByteArray &msg, const QByteArray } else if (msg == "exit") { // shutdown everything -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: exit"; #endif QCoreApplication::quit(); } } -void QQnxNavigatorThread::readData() +void QQnxNavigatorEventHandler::readData() { -#if defined(QQNXNAVIGATORTHREAD_DEBUG) +#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "QQNX: reading navigator data"; #endif // allocate buffer for pps data diff --git a/src/plugins/platforms/qnx/qqnxnavigatorthread.h b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h index 40b217db73..2e0bd1fa14 100644 --- a/src/plugins/platforms/qnx/qqnxnavigatorthread.h +++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h @@ -39,31 +39,30 @@ ** ****************************************************************************/ -#ifndef QQNXNAVIGATORTHREAD_H -#define QQNXNAVIGATORTHREAD_H +#ifndef QQNXNAVIGATOREVENTHANDLER_H +#define QQNXNAVIGATOREVENTHANDLER_H -#include <QThread> +#include <QObject> QT_BEGIN_NAMESPACE class QQnxScreen; class QSocketNotifier; -class QQnxNavigatorThread : public QThread +class QQnxNavigatorEventHandler : public QObject { Q_OBJECT public: - QQnxNavigatorThread(QQnxScreen &primaryScreen); - virtual ~QQnxNavigatorThread(); + QQnxNavigatorEventHandler(QQnxScreen &primaryScreen); + virtual ~QQnxNavigatorEventHandler(); -protected: - virtual void run(); +public Q_SLOTS: + void start(); private Q_SLOTS: void readData(); private: - void shutdown(); void parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id); void replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat); void handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id); @@ -75,4 +74,4 @@ private: QT_END_NAMESPACE -#endif // QQNXNAVIGATORTHREAD_H +#endif // QQNXNAVIGATOREVENTHANDLER_H diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index e0e3d6d57d..cd77c3088a 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -207,7 +207,7 @@ void QQnxScreen::setRotation(int rotation) m_rootWindow->setRotation(rotation); // Swap dimensions if we've rotated 90 or 270 from initial orientation - if (isOrthogonal(m_currentRotation, rotation)) { + if (isOrthogonal(m_initialRotation, rotation)) { m_currentGeometry = QRect(0, 0, m_initialGeometry.height(), m_initialGeometry.width()); m_currentPhysicalSize = QSize(m_initialPhysicalSize.height(), m_initialPhysicalSize.width()); } else { diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp index 9d7fe92660..20c89d3e32 100644 --- a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp +++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp @@ -46,6 +46,8 @@ #include <QtGui/QPlatformWindow> #include <QtCore/QDebug> +#include <QtCore/QSocketNotifier> +#include <QtCore/private/qcore_unix_p.h> #include <errno.h> #include <fcntl.h> @@ -65,17 +67,17 @@ static QQnxVirtualKeyboard *s_instance = 0; // Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP. #define KEYBOARD_SHADOW_HEIGHT 8 -QQnxVirtualKeyboard::QQnxVirtualKeyboard() : - m_encoder(NULL), - m_decoder(NULL), - m_buffer(NULL), - m_height(0), - m_fd(-1), - m_keyboardMode(Default), - m_visible(false), - m_locale(QLatin1String("en_US")) +QQnxVirtualKeyboard::QQnxVirtualKeyboard() + : m_encoder(0), + m_decoder(0), + m_buffer(0), + m_height(0), + m_fd(-1), + m_keyboardMode(Default), + m_visible(false), + m_locale(QLatin1String("en_US")), + m_readNotifier(0) { - connect(); } QQnxVirtualKeyboard::~QQnxVirtualKeyboard() @@ -88,12 +90,24 @@ QQnxVirtualKeyboard& QQnxVirtualKeyboard::instance() { if (!s_instance) { s_instance = new QQnxVirtualKeyboard(); - s_instance->start(); + + // delay invocation of start() to the time the event loop is up and running + // needed to have the QThread internals of the main thread properly initialized + QMetaObject::invokeMethod(s_instance, "start", Qt::QueuedConnection); } return *s_instance; } +void QQnxVirtualKeyboard::start() +{ +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + qDebug() << "QQNX: starting keyboard event processing"; +#endif + if (!connect()) + return; +} + /* static */ void QQnxVirtualKeyboard::destroy() { @@ -105,35 +119,28 @@ void QQnxVirtualKeyboard::destroy() void QQnxVirtualKeyboard::close() { - if (m_fd) { - // any reads will fail after we close the fd, which is basically what we want. - ::close(m_fd); - } - - // Wait for the thread to die (should be immediate), then continue the cleanup. - wait(); + delete m_readNotifier; + m_readNotifier = 0; - if (m_fd) { + if (m_fd != -1) { + ::close(m_fd); m_fd = -1; } - - if (m_decoder) - { + if (m_decoder) { pps_decoder_cleanup(m_decoder); delete m_decoder; - m_decoder = NULL; + m_decoder = 0; } - if (m_encoder) - { + if (m_encoder) { pps_encoder_cleanup(m_encoder); delete m_encoder; - m_encoder = NULL; + m_encoder = 0; } delete [] m_buffer; - m_buffer = NULL; + m_buffer = 0; } bool QQnxVirtualKeyboard::connect() @@ -165,7 +172,8 @@ bool QQnxVirtualKeyboard::connect() if (!queryPPSInfo()) return false; - start(); + m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read); + QObject::connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(ppsDataReady())); return true; } @@ -192,74 +200,63 @@ void QQnxVirtualKeyboard::notifyClientActiveStateChange(bool active) hideKeyboard(); } -void QQnxVirtualKeyboard::run() -{ - ppsDataReady(); -} - void QQnxVirtualKeyboard::ppsDataReady() { - while (1) { - ssize_t nread = read(m_fd, m_buffer, ms_bufferSize - 1); + ssize_t nread = qt_safe_read(m_fd, m_buffer, ms_bufferSize - 1); #ifdef QQNXVIRTUALKEYBOARD_DEBUG - qDebug() << "QQNX: keyboardMessage size: " << nread; + qDebug() << "QQNX: keyboardMessage size: " << nread; #endif - if (nread < 0) - break; + if (nread < 0){ + connect(); // reconnect + return; + } - // nread is the real space necessary, not the amount read. - if (static_cast<size_t>(nread) > ms_bufferSize - 1) { - qCritical("QQnxVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1); - break; - } + // nread is the real space necessary, not the amount read. + if (static_cast<size_t>(nread) > ms_bufferSize - 1) { + qCritical("QQnxVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1); + connect(); // reconnect + return; + } - m_buffer[nread] = 0; - pps_decoder_parse_pps_str(m_decoder, m_buffer); - pps_decoder_push(m_decoder, NULL); + m_buffer[nread] = 0; + pps_decoder_parse_pps_str(m_decoder, m_buffer); + pps_decoder_push(m_decoder, NULL); #ifdef QQNXVIRTUALKEYBOARD_DEBUG - pps_decoder_dump_tree(m_decoder, stderr); + pps_decoder_dump_tree(m_decoder, stderr); #endif - const char *value; - if (pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK) { - qCritical("QQnxVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]"); - continue; - } - - if (pps_decoder_get_string(m_decoder, "msg", &value) == PPS_DECODER_OK) { - if (strcmp(value, "show") == 0) { - const bool oldVisible = m_visible; - m_visible = true; - handleKeyboardStateChangeMessage(true); - if (oldVisible != m_visible) - emit visibilityChanged(m_visible); - } else if (strcmp(value, "hide") == 0) { - const bool oldVisible = m_visible; - m_visible = false; - handleKeyboardStateChangeMessage(false); - if (oldVisible != m_visible) - emit visibilityChanged(m_visible); - } else if (strcmp(value, "info") == 0) - handleKeyboardInfoMessage(); - else if (strcmp(value, "connect") == 0) { } - else - qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]"); - } else if (pps_decoder_get_string(m_decoder, "res", &value) == PPS_DECODER_OK) { - if (strcmp(value, "info") == 0) - handleKeyboardInfoMessage(); - else - qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]"); - } else - qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS message type"); + const char *value; + if (pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK) { + qCritical("QQnxVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]"); + return; } -#ifdef QQNXVIRTUALKEYBOARD_DEBUG - qDebug() << "QQNX: exiting keyboard thread"; -#endif - - if (m_decoder) - pps_decoder_cleanup(m_decoder); + if (pps_decoder_get_string(m_decoder, "msg", &value) == PPS_DECODER_OK) { + if (strcmp(value, "show") == 0) { + const bool oldVisible = m_visible; + m_visible = true; + handleKeyboardStateChangeMessage(true); + if (oldVisible != m_visible) + emit visibilityChanged(m_visible); + } else if (strcmp(value, "hide") == 0) { + const bool oldVisible = m_visible; + m_visible = false; + handleKeyboardStateChangeMessage(false); + if (oldVisible != m_visible) + emit visibilityChanged(m_visible); + } else if (strcmp(value, "info") == 0) + handleKeyboardInfoMessage(); + else if (strcmp(value, "connect") == 0) { } + else + qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]"); + } else if (pps_decoder_get_string(m_decoder, "res", &value) == PPS_DECODER_OK) { + if (strcmp(value, "info") == 0) + handleKeyboardInfoMessage(); + else + qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]"); + } else + qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS message type"); } void QQnxVirtualKeyboard::handleKeyboardInfoMessage() diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h index 21b2e8736c..73a296fb9f 100644 --- a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h +++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h @@ -42,7 +42,7 @@ #ifndef VIRTUALKEYBOARD_H_ #define VIRTUALKEYBOARD_H_ -#include <QtCore/QThread> +#include <QtCore/QObject> #include <QtCore/QLocale> #include <QtGui/QPlatformScreen> #include <QtGui/QWindowSystemInterface> @@ -52,10 +52,12 @@ #include <string> #include <sys/pps.h> +class QSocketNotifier; + QT_BEGIN_NAMESPACE /* Shamelessly copied from the browser - this should be rewritten once we have a proper PPS wrapper class */ -class QQnxVirtualKeyboard : public QThread +class QQnxVirtualKeyboard : public QObject { Q_OBJECT public: @@ -83,10 +85,16 @@ public: bool isVisible() const { return m_visible; } QLocale locale() const { return m_locale; } +public Q_SLOTS: + void start(); + Q_SIGNALS: void localeChanged(const QLocale &locale); void visibilityChanged(bool visible); +private Q_SLOTS: + void ppsDataReady(); + private: QQnxVirtualKeyboard(); virtual ~QQnxVirtualKeyboard(); @@ -94,7 +102,6 @@ private: // Will be called internally if needed. bool connect(); void close(); - void ppsDataReady(); bool queryPPSInfo(); void handleKeyboardInfoMessage(); void handleKeyboardStateChangeMessage(bool visible); @@ -110,9 +117,6 @@ private: void addPhoneModeOptions(); void addPinModeOptions(); - // QThread overrides - virtual void run(); - pps_encoder_t *m_encoder; pps_decoder_t *m_decoder; char *m_buffer; @@ -121,6 +125,7 @@ private: KeyboardMode m_keyboardMode; bool m_visible; QLocale m_locale; + QSocketNotifier *m_readNotifier; // Path to keyboardManager in PPS. static const char *ms_PPSPath; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index f61e40ef77..17420d271d 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -362,7 +362,7 @@ QString QWindowsContext::registerWindowClass(const QWindow *w, bool isGL) style = CS_DBLCLKS; if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) { if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) { + && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based))) { style |= CS_DROPSHADOW; } cname += QStringLiteral("QToolTip"); @@ -375,7 +375,7 @@ QString QWindowsContext::registerWindowClass(const QWindow *w, bool isGL) cname += QStringLiteral("QPopup"); style = CS_DBLCLKS|CS_SAVEBITS; if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) + && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based))) style |= CS_DROPSHADOW; icon = false; } else { diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README index 17e8bb53eb..eede0cc149 100644 --- a/src/plugins/platforms/xcb/README +++ b/src/plugins/platforms/xcb/README @@ -1,3 +1,5 @@ +Requires libxcb >= 1.5. + Required packages: libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index b7369525a5..6e90594631 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -58,6 +58,7 @@ #include <qpainter.h> #include <qscreen.h> +#include <algorithm> QT_BEGIN_NAMESPACE class QXcbShmImage : public QXcbObject diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 8b66ef4603..a076dd4282 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -367,7 +367,11 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) QString QXcbScreen::name() const { - return connection()->displayName() + QLatin1String(".") + QString::number(screenNumber()); + QByteArray displayName = connection()->displayName(); + int dotPos = displayName.lastIndexOf('.'); + if (dotPos != -1) + displayName.truncate(dotPos); + return displayName + QLatin1Char('.') + QString::number(screenNumber()); } QT_END_NAMESPACE diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp index 9444038997..c5c60ae5cc 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp @@ -58,12 +58,13 @@ QWindowsPrinterSupport::QWindowsPrinterSupport() LPBYTE buffer = new BYTE[needed]; if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) { PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer); - QPrinterInfo defPrn = defaultPrinter(); + QString defaultPrinterName; + QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, QString(), QString()); for (uint i = 0; i < returned; ++i) { QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); QPrinterInfo printerInfo(printerName); - if (printerInfo.printerName() == defPrn.printerName()) + if (printerInfo.printerName() == defaultPrinterName) printerInfo.d_ptr->isDefault = true; mPrinterList.append(printerInfo); } @@ -87,15 +88,9 @@ QPaintEngine *QWindowsPrinterSupport::createPaintEngine(QPrintEngine *engine, QP return static_cast<QWin32PrintEngine *>(engine); } -QList<QPrinter::PaperSize> QWindowsPrinterSupport::supportedPaperSizes(const QPrinterInfo &) const +QList<QPrinter::PaperSize> QWindowsPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const { - QList<QPrinter::PaperSize> returnList; - foreach (const QPrinterInfo &info, mPrinterList) { - foreach (const QPrinter::PaperSize supportedSize, info.supportedPaperSizes()) - if (!returnList.contains(supportedSize)) - returnList.append(supportedSize); - } - return returnList; + return QWin32PrintEngine::supportedPaperSizes(printerInfo); } QList<QPrinterInfo> QWindowsPrinterSupport::availablePrinters() |