diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-10-24 12:48:39 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-10-24 12:48:42 +0200 |
commit | 840f6a40e6218992b5b9d451ee3c0886a4846c89 (patch) | |
tree | 2b808decc7adf5218b810d2de6b45c5a8b4cfc42 /src/plugins/platforms | |
parent | 109bf980b37fed405c6c1eb14cb9c83ff897e389 (diff) | |
parent | 2e3870fe37d36ccf4bd84eb90e1d5e08ad00c1bc (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: Ie56539b2e0be611a363b5f15ae5412a78d6945a2
Diffstat (limited to 'src/plugins/platforms')
26 files changed, 346 insertions, 80 deletions
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/src/androidjniaccessibility.cpp index 07f3371e72..a27d9f5aed 100644 --- a/src/plugins/platforms/android/src/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/src/androidjniaccessibility.cpp @@ -164,7 +164,7 @@ if (!clazz) { \ //__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); -#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, VALUE) \ +#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, ...) \ { \ jclass clazz = env->GetObjectClass(OBJECT); \ jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \ @@ -172,7 +172,7 @@ if (!clazz) { \ __android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ return; \ } \ - env->CallVoidMethod(OBJECT, method, VALUE); \ + env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \ } @@ -201,9 +201,21 @@ if (!clazz) { \ } QAccessible::State state = iface->state(); - QString desc = iface->text(QAccessible::Name); + // try to fill in the text property, this is what the screen reader reads + QString desc = iface->text(QAccessible::Value); + if (desc.isEmpty()) + desc = iface->text(QAccessible::Name); if (desc.isEmpty()) desc = iface->text(QAccessible::Description); + if (QAccessibleTextInterface *textIface = iface->textInterface()) { + if (textIface->selectionCount() > 0) { + int startSelection; + int endSelection; + textIface->selection(0, &startSelection, &endSelection); + CALL_METHOD(node, "setTextSelection", "(II)V", startSelection, endSelection) + } + } + if ((iface->role() != QAccessible::NoRole) && (iface->role() != QAccessible::Client) && (iface->role() != QAccessible::Pane)) { diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp index 4a2d87d6a4..30d4e69afe 100644 --- a/src/plugins/platforms/android/src/androidjniinput.cpp +++ b/src/plugins/platforms/android/src/androidjniinput.cpp @@ -228,6 +228,9 @@ namespace QtAndroidInput return; QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration(); + if (!platformIntegration) + return; + QTouchDevice *touchDevice = platformIntegration->touchDevice(); if (touchDevice == 0) { touchDevice = new QTouchDevice; @@ -271,8 +274,8 @@ namespace QtAndroidInput case 0x00000005: return Qt::Key_Call; - case 0x0000001b: - return Qt::Key_WebCam; + case 0x0000001b: // KEYCODE_CAMERA + return Qt::Key_Camera; case 0x0000001c: return Qt::Key_Clear; @@ -280,7 +283,7 @@ namespace QtAndroidInput case 0x00000037: return Qt::Key_Comma; - case 0x00000043: + case 0x00000043: // KEYCODE_DEL return Qt::Key_Backspace; case 0x00000017: // KEYCODE_DPAD_CENTER @@ -398,6 +401,27 @@ namespace QtAndroidInput case 0x00000018: return Qt::Key_VolumeUp; + case 0x00000011: // KEYCODE_STAR + return Qt::Key_Asterisk; + + case 0x00000012: // KEYCODE_POUND + return Qt::Key_NumberSign; + + case 0x00000050: // KEYCODE_FOCUS + return Qt::Key_CameraFocus; + + case 0x00000070: // KEYCODE_FORWARD_DEL + return Qt::Key_Delete; + + case 0x00000080: // KEYCODE_MEDIA_CLOSE + return Qt::Key_Close; + + case 0x00000081: // KEYCODE_MEDIA_EJECT + return Qt::Key_Eject; + + case 0x00000082: // KEYCODE_MEDIA_RECORD + return Qt::Key_MediaRecord; + case 0x000000b7: // KEYCODE_PROG_RED return Qt::Key_Red; @@ -416,13 +440,30 @@ namespace QtAndroidInput case 0x000000a7: // KEYCODE_CHANNEL_DOWN return Qt::Key_ChannelDown; + case 0x000000a8: // KEYCODE_ZOOM_IN + return Qt::Key_ZoomIn; + + case 0x000000a9: // KEYCODE_ZOOM_OUT + return Qt::Key_ZoomOut; + + case 0x000000af: // KEYCODE_CAPTIONS + return Qt::Key_Subtitle; + + case 0x000000d0: // KEYCODE_CALENDAR + return Qt::Key_Calendar; + + case 0x000000d1: // KEYCODE_MUSIC + return Qt::Key_Music; + + case 0x000000d2: // KEYCODE_CALCULATOR + return Qt::Key_Calculator; + case 0x00000000: // KEYCODE_UNKNOWN - case 0x00000011: // KEYCODE_STAR ?!?!? - case 0x00000012: // KEYCODE_POUND ?!?!? + return Qt::Key_unknown; + case 0x00000053: // KEYCODE_NOTIFICATION ?!?!? case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!? case 0x00000044: // KEYCODE_GRAVE ?!?!? - case 0x00000050: // KEYCODE_FOCUS ?!?!? return Qt::Key_Any; default: @@ -447,7 +488,7 @@ namespace QtAndroidInput mapAndroidKey(key), modifiers, QChar(unicode), - true); + false); } static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier) @@ -467,7 +508,7 @@ namespace QtAndroidInput mapAndroidKey(key), modifiers, QChar(unicode), - true); + false); } diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index b51c15c5d9..5c9ca798a8 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -419,14 +419,11 @@ static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobj static void *startMainMethod(void */*data*/) { - char const **params; - params = static_cast<char const **>(malloc(m_applicationParams.length() * sizeof(char *))); + QVarLengthArray<const char *> params(m_applicationParams.size()); for (int i = 0; i < m_applicationParams.size(); i++) params[i] = static_cast<const char *>(m_applicationParams[i].constData()); - int ret = m_main(m_applicationParams.length(), const_cast<char **>(params)); - - free(params); + int ret = m_main(m_applicationParams.length(), const_cast<char **>(params.data())); Q_UNUSED(ret); if (m_mainLibraryHnd) { diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index 9ce382bd53..a3db421de9 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -42,7 +42,6 @@ #include "qandroidplatformintegration.h" #include "qabstracteventdispatcher.h" #include "androidjnimain.h" -#include <QtGui/private/qpixmap_raster_p.h> #include <QtGui/qguiapplication.h> #include <qpa/qwindowsysteminterface.h> #include <QThread> diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp index 36247e86f9..253c22a12f 100644 --- a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp @@ -67,9 +67,11 @@ void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatform void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) { QMutexLocker lock(&m_menuItemsMutex); - m_menuItems.erase(qFind(m_menuItems.begin(), - m_menuItems.end(), - static_cast<QAndroidPlatformMenuItem *>(menuItem))); + PlatformMenuItemsType::iterator it = qFind(m_menuItems.begin(), + m_menuItems.end(), + static_cast<QAndroidPlatformMenuItem *>(menuItem)); + if (it != m_menuItems.end()) + m_menuItems.erase(it); } void QAndroidPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 05bf657c1f..7f0f07e912 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -201,9 +201,11 @@ public: // for QNSView bool m_isExposed; int m_registerTouchCount; bool m_resizableTransientParent; + bool m_overrideBecomeKey; static const int NoAlertRequest; NSInteger m_alertRequest; + id monitor; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 7bdfd12314..845cc1202f 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -160,7 +160,9 @@ static bool isMouseEvent(NSEvent *ev) // Only tool or dialog windows should become key: if (m_cocoaPlatformWindow - && (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog)) + && (m_cocoaPlatformWindow->m_overrideBecomeKey || + m_cocoaPlatformWindow->window()->type() == Qt::Tool || + m_cocoaPlatformWindow->window()->type() == Qt::Dialog)) return YES; return NO; } @@ -212,7 +214,9 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_isExposed(false) , m_registerTouchCount(0) , m_resizableTransientParent(false) + , m_overrideBecomeKey(false) , m_alertRequest(NoAlertRequest) + , monitor(nil) { #ifdef QT_COCOA_ENABLE_WINDOW_DEBUG qDebug() << "QCocoaWindow::QCocoaWindow" << this; @@ -367,6 +371,11 @@ void QCocoaWindow::setVisible(bool visible) if ((window()->type() == Qt::Popup || window()->type() == Qt::Dialog || window()->type() == Qt::Tool) && [m_nsWindow isKindOfClass:[NSPanel class]]) { [(NSPanel *)m_nsWindow setWorksWhenModal:YES]; + if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) { + monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDown handler:^(NSEvent *) { + QWindowSystemInterface::handleMouseEvent(window(), QPointF(-1, -1), QPointF(window()->framePosition() - QPointF(1, 1)), Qt::LeftButton); + }]; + } } } } @@ -403,6 +412,10 @@ void QCocoaWindow::setVisible(bool visible) } else { [m_contentView setHidden:YES]; } + if (monitor && window()->type() == Qt::Popup) { + [NSEvent removeMonitor:monitor]; + monitor = nil; + } if (parentCocoaWindow && window()->type() == Qt::Popup) { parentCocoaWindow->m_activePopupWindow = 0; if (m_resizableTransientParent @@ -450,7 +463,6 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) { Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask)); NSInteger styleMask = NSBorderlessWindowMask; - if ((type & Qt::Popup) == Qt::Popup) { if (!windowIsPopupType(type) && !(flags & Qt::FramelessWindowHint)) styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | @@ -458,14 +470,21 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) } else { // Filter flags for supported properties flags &= Qt::WindowType_Mask | Qt::FramelessWindowHint | Qt::WindowTitleHint | - Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint; + Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint; if (flags == Qt::Window) { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); } else if ((flags & Qt::Dialog) == Qt::Dialog) { - if (window()->modality() == Qt::NonModal) + if (flags & Qt::CustomizeWindowHint) { + styleMask = NSResizableWindowMask; + if (flags & Qt::WindowTitleHint) + styleMask |= NSTitledWindowMask; + if (flags & Qt::WindowCloseButtonHint) + styleMask |= NSClosableWindowMask; + if (flags & Qt::WindowMinimizeButtonHint) + styleMask |= NSMiniaturizableWindowMask; + } else { styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask; - else - styleMask = NSResizableWindowMask | NSTitledWindowMask; + } } else if (!(flags & Qt::FramelessWindowHint)) { if ((flags & Qt::Dialog) || (flags & Qt::WindowMaximizeButtonHint)) styleMask |= NSResizableWindowMask; @@ -661,6 +680,8 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) if (!m_nsWindow) return false; + m_overrideBecomeKey = grab; + if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; else if (!grab && [m_nsWindow isKeyWindow]) @@ -673,6 +694,8 @@ bool QCocoaWindow::setMouseGrabEnabled(bool grab) if (!m_nsWindow) return false; + m_overrideBecomeKey = grab; + if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; else if (!grab && [m_nsWindow isKeyWindow]) @@ -843,10 +866,9 @@ NSWindow * QCocoaWindow::createNSWindow() // before the window is shown and needs a proper window.). if ((type & Qt::Popup) == Qt::Popup) [window setHasShadow:YES]; - else { - setWindowShadow(flags); - [window setHidesOnDeactivate: NO]; - } + else + setWindowShadow(flags); + [window setHidesOnDeactivate: NO]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 8813a934bf..f90fc6b205 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -208,6 +208,22 @@ static QTouchDevice *touchDevice = 0; if ([self window]) [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]]; } + +- (QWindow *)topLevelWindow +{ + QWindow *focusWindow = m_window; + + // For widgets we need to do a bit of trickery as the window + // to activate is the window of the top-level widget. + if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) { + while (focusWindow->parent()) { + focusWindow = focusWindow->parent(); + } + } + + return focusWindow; +} + - (void)updateGeometry { QRect geometry; @@ -457,16 +473,7 @@ static QTouchDevice *touchDevice = 0; { if (m_window->flags() & Qt::WindowTransparentForInput) return NO; - QWindow *focusWindow = m_window; - - // For widgets we need to do a bit of trickery as the window - // to activate is the window of the top-level widget. - if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) { - while (focusWindow->parent()) { - focusWindow = focusWindow->parent(); - } - } - QWindowSystemInterface::handleWindowActivated(focusWindow); + QWindowSystemInterface::handleWindowActivated([self topLevelWindow]); return YES; } @@ -968,6 +975,102 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, touchDevice, points); } +#ifndef QT_NO_GESTURES +//#define QT_COCOA_ENABLE_GESTURE_DEBUG +- (void)magnifyWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "magnifyWithEvent" << [event magnification]; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::ZoomNativeGesture, + [event magnification], windowPoint, screenPoint); +} + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 +- (void)smartMagnifyWithEvent:(NSEvent *)event +{ + static bool zoomIn = true; +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "smartMagnifyWithEvent" << zoomIn; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SmartZoomNativeGesture, + zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint); + zoomIn = !zoomIn; +} +#endif + +- (void)rotateWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "rotateWithEvent" << [event rotation]; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::RotateNativeGesture, + -[event rotation], windowPoint, screenPoint); +} + +- (void)swipeWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "swipeWithEvent" << [event deltaX] << [event deltaY]; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + + qreal angle = 0.0f; + if ([event deltaX] == 1) + angle = 180.0f; + else if ([event deltaX] == -1) + angle = 0.0f; + else if ([event deltaY] == 1) + angle = 90.0f; + else if ([event deltaY] == -1) + angle = 270.0f; + + QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SwipeNativeGesture, + angle, windowPoint, screenPoint); +} + +- (void)beginGestureWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "beginGestureWithEvent"; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::BeginNativeGesture, + windowPoint, screenPoint); +} + +- (void)endGestureWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "endGestureWithEvent"; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::EndNativeGesture, + windowPoint, screenPoint); +} +#endif // QT_NO_GESTURES + #ifndef QT_NO_WHEELEVENT - (void)scrollWheel:(NSEvent *)theEvent { @@ -1124,10 +1227,12 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) if (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff) text = QCFString::toQString(characters); + QWindow *focusWindow = [self topLevelWindow]; + if (eventType == QEvent::KeyPress) { if (m_composingText.isEmpty()) - m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(m_window, timestamp, keyCode, modifiers, text); + m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(focusWindow, timestamp, keyCode, modifiers, text); QObject *fo = QGuiApplication::focusObject(); if (m_sendKeyEvent && fo) { @@ -1144,7 +1249,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) } if (m_sendKeyEvent && m_composingText.isEmpty()) - QWindowSystemInterface::handleExtendedKeyEvent(m_window, timestamp, QEvent::Type(eventType), keyCode, modifiers, + QWindowSystemInterface::handleExtendedKeyEvent(focusWindow, timestamp, QEvent::Type(eventType), keyCode, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat]); m_sendKeyEvent = false; diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp index 5b4c958616..b56d75a16e 100644 --- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp +++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp @@ -282,9 +282,12 @@ QDirectFbKeyMap::QDirectFbKeyMap() insert(DIKS_MENU , Qt::Key_Menu); insert(DIKS_HELP , Qt::Key_Help); + insert(DIKS_CD , Qt::Key_CD); insert(DIKS_INTERNET , Qt::Key_HomePage); insert(DIKS_MAIL , Qt::Key_LaunchMail); insert(DIKS_FAVORITES , Qt::Key_Favorites); + insert(DIKS_PHONE , Qt::Key_Phone); + insert(DIKS_TIME , Qt::Key_Time); insert(DIKS_RED , Qt::Key_Red); insert(DIKS_GREEN , Qt::Key_Green); @@ -307,6 +310,7 @@ QDirectFbKeyMap::QDirectFbKeyMap() insert(DIKS_NEXT , Qt::Key_MediaNext); insert(DIKS_REWIND , Qt::Key_AudioRewind); insert(DIKS_FASTFORWARD , Qt::Key_AudioForward); + insert(DIKS_SUBTITLE , Qt::Key_Subtitle); insert(DIKS_F1 , Qt::Key_F1); insert(DIKS_F2 , Qt::Key_F2); diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index f7df792362..3dd9c7ad9f 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -213,7 +213,7 @@ static int infoPlistValue(NSString* key, int defaultValue) return value ? [value intValue] : defaultValue; } -extern "C" int qtmn(int argc, char *argv[]) +extern "C" int __attribute__((weak)) main(int argc, char *argv[]) { @autoreleasepool { size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads @@ -248,7 +248,18 @@ enum SetJumpResult kJumpedFromUserMainTrampoline, }; -extern "C" int main(int argc, char *argv[]); +// We define qt_main so that user_main_trampoline() will not cause +// missing symbols in the case of hybrid applications that don't +// user our main wrapper. Since the symbol is weak, it will not +// get used or cause a clash in the normal Qt application usecase, +// where we rename main to qt_main. +extern "C" int __attribute__((weak)) qt_main(int argc, char *argv[]) +{ + Q_UNUSED(argc); + Q_UNUSED(argv); + + Q_UNREACHABLE(); +} static void __attribute__((noinline, noreturn)) user_main_trampoline() { @@ -261,7 +272,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline() strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]); } - int exitCode = main(argc, argv); + int exitCode = qt_main(argc, argv); delete[] argv; qEventDispatcherDebug() << "Returned from main with exit code " << exitCode; @@ -496,6 +507,7 @@ void QIOSEventDispatcher::checkIfEventLoopShouldExit() void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) { + Q_UNUSED(activity); Q_ASSERT(activity == kCFRunLoopExit); m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes); diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp index aa2687da30..977df8abd0 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp @@ -56,9 +56,8 @@ QT_BEGIN_NAMESPACE QLinuxFbIntegration::QLinuxFbIntegration(const QStringList ¶mList) : m_fontDb(new QGenericUnixFontDatabase()) { - m_primaryScreen = new QLinuxFbScreen; - if (m_primaryScreen->initialize(paramList)) - screenAdded(m_primaryScreen); + m_primaryScreen = new QLinuxFbScreen(paramList); + screenAdded(m_primaryScreen); } QLinuxFbIntegration::~QLinuxFbIntegration() @@ -66,6 +65,12 @@ QLinuxFbIntegration::~QLinuxFbIntegration() delete m_primaryScreen; } +void QLinuxFbIntegration::initialize() +{ + if (!m_primaryScreen->initialize()) + qWarning("linuxfb: Failed to initialize screen"); +} + bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h index 6de9ac9992..a213f83c6f 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h @@ -56,14 +56,16 @@ public: QLinuxFbIntegration(const QStringList ¶mList); ~QLinuxFbIntegration(); - bool hasCapability(QPlatformIntegration::Capability cap) const; + void initialize() Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + + QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; - QPlatformWindow *createPlatformWindow(QWindow *window) const; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QAbstractEventDispatcher *createEventDispatcher() const; QList<QPlatformScreen *> screens() const; - QPlatformFontDatabase *fontDatabase() const; private: QLinuxFbScreen *m_primaryScreen; diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index ad5206ba41..4f9284da7f 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -62,6 +62,10 @@ #include <linux/fb.h> +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) +#include <QtPlatformSupport/private/qdevicediscovery_p.h> +#endif + QT_BEGIN_NAMESPACE static int openFramebufferDevice(const QString &dev) @@ -292,8 +296,8 @@ static void blankScreen(int fd, bool on) ioctl(fd, FBIOBLANK, on ? VESA_POWERDOWN : VESA_NO_BLANKING); } -QLinuxFbScreen::QLinuxFbScreen() - : mFbFd(-1), mBlitter(0) +QLinuxFbScreen::QLinuxFbScreen(const QStringList &args) + : mArgs(args), mFbFd(-1), mBlitter(0) { } @@ -312,7 +316,7 @@ QLinuxFbScreen::~QLinuxFbScreen() delete mBlitter; } -bool QLinuxFbScreen::initialize(const QStringList &args) +bool QLinuxFbScreen::initialize() { QRegExp ttyRx(QLatin1String("tty=(.*)")); QRegExp fbRx(QLatin1String("fb=(.*)")); @@ -326,7 +330,7 @@ bool QLinuxFbScreen::initialize(const QStringList &args) bool doSwitchToGraphicsMode = true; // Parse arguments - foreach (const QString &arg, args) { + foreach (const QString &arg, mArgs) { if (arg == QLatin1String("nographicsmodeswitch")) doSwitchToGraphicsMode = false; else if (sizeRx.indexIn(arg) != -1) @@ -341,8 +345,15 @@ bool QLinuxFbScreen::initialize(const QStringList &args) userMmSize = QSize(mmSizeRx.cap(1).toInt(), mmSizeRx.cap(2).toInt()); } - if (fbDevice.isEmpty()) - fbDevice = QLatin1String("/dev/fb0"); // ## auto-detect + if (fbDevice.isEmpty()) { + fbDevice = QLatin1String("/dev/fb0"); + if (!QFile::exists(fbDevice)) + fbDevice = QLatin1String("/dev/graphics/fb0"); + if (!QFile::exists(fbDevice)) { + qWarning("Unable to figure out framebuffer device. Specify it manually."); + return false; + } + } // Open the device mFbFd = openFramebufferDevice(fbDevice); @@ -387,7 +398,19 @@ bool QLinuxFbScreen::initialize(const QStringList &args) QFbScreen::initializeCompositor(); mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat); - mCursor = new QFbCursor(this); + + QByteArray hideCursorVal = qgetenv("QT_QPA_FB_HIDECURSOR"); + bool hideCursor = true; // default to true to prevent the cursor showing up with the subclass on Android + if (hideCursorVal.isEmpty()) { +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse)); + hideCursor = dis->scanConnectedDevices().isEmpty(); +#endif + } else { + hideCursor = hideCursorVal.toInt() != 0; + } + if (!hideCursor) + mCursor = new QFbCursor(this); mTtyFd = openTtyDevice(ttyDevice); if (mTtyFd == -1) diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h index d34104c6e1..32cd263063 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h @@ -53,15 +53,16 @@ class QLinuxFbScreen : public QFbScreen { Q_OBJECT public: - QLinuxFbScreen(); + QLinuxFbScreen(const QStringList &args); ~QLinuxFbScreen(); - bool initialize(const QStringList &args); + bool initialize(); public slots: QRegion doRedraw(); private: + QStringList mArgs; int mFbFd; int mTtyFd; diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp index 355f52c46e..34e8150928 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.cpp +++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp @@ -124,7 +124,15 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext) if (m_eglConfig == 0) qFatal("QQnxGLContext: failed to find EGL config"); - m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs()); + EGLContext shareContext = EGL_NO_CONTEXT; + if (m_glContext) { + QQnxGLContext *qshareContext = dynamic_cast<QQnxGLContext*>(m_glContext->shareHandle()); + if (qshareContext) { + shareContext = qshareContext->m_eglContext; + } + } + + m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs()); if (m_eglContext == EGL_NO_CONTEXT) { checkEGLError("eglCreateContext"); qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError()); diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 6c3fd08a41..dd8cf2131a 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -446,7 +446,7 @@ void QQnxScreen::addWindow(QQnxWindow *window) m_childWindows.push_back(window); updateHierarchy(); } else { -#if !defined(Q_OS_BLACKBERRY_TABLET) +#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET) m_coverWindow = window; #endif } diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index a129380575..3969a09098 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -562,13 +562,11 @@ void QQnxWindow::initWindow() setScreen(static_cast<QQnxScreen *>(window()->screen()->handle())); if (window()->type() == Qt::CoverWindow) { -#if !defined(Q_OS_BLACKBERRY_TABLET) +#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET) screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(), SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window); -#if defined(Q_OS_BLACKBERRY) m_cover.reset(new QQnxNavigatorCover); #endif -#endif // Q_OS_BLACKBERRY_TABLET m_exposed = false; } diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index ee5b6189b2..f6ed9447ef 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -204,6 +204,9 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI case WM_DISPLAYCHANGE: return QtWindows::DisplayChangedEvent; case WM_THEMECHANGED: +#ifdef WM_SYSCOLORCHANGE // Windows 7: Handle color change as theme change (QTBUG-34170). + case WM_SYSCOLORCHANGE: +#endif return QtWindows::ThemeChanged; case WM_DWMCOMPOSITIONCHANGED: return QtWindows::CompositionSettingsChanged; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 783d50a26a..85b03673ac 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -954,7 +954,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, qGuiAppPriv->commitData(); if (lParam & ENDSESSION_LOGOFF) - _flushall(); + fflush(NULL); return !sessionManager->wasCanceled(); } diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 0ecbf44194..832ce24354 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -578,8 +578,8 @@ bool QWindowsDialogHelperBase<BaseClass>::show(Qt::WindowFlags, m_ownerWindow = 0; } if (QWindowsContext::verboseDialogs) - qDebug("%s modal=%d native=%p parent=%p" , - __FUNCTION__, modal, m_nativeDialog.data(), m_ownerWindow); + qDebug("%s modal=%d modal supported? %d native=%p parent=%p" , + __FUNCTION__, modal, supportsNonModalDialog(parent), m_nativeDialog.data(), m_ownerWindow); if (!modal && !supportsNonModalDialog(parent)) return false; // Was it changed in-between? if (!ensureNativeDialog()) @@ -1766,7 +1766,9 @@ static int CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg, return dialog->existingDirCallback(hwnd, uMsg, lParam); } -#ifdef Q_CC_MINGW +/* The correct declaration of the SHGetPathFromIDList symbol is + * being used in mingw-w64 as of r6215, which is a v3 snapshot. */ +#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3) typedef ITEMIDLIST *qt_LpItemIdList; #else typedef PIDLIST_ABSOLUTE qt_LpItemIdList; diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 4a5d7b5a78..1a5c1a2e0c 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -395,8 +395,19 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() const int currentDevice = m_devices.at(m_currentDevice).currentDevice; const int currentPointer = m_devices.at(m_currentDevice).currentPointerType; - // When entering proximity, the tablet driver snaps the mouse pointer to the - // tablet position scaled to the virtual desktop and keeps it in sync. + // The tablet can be used in 2 different modes, depending on it settings: + // 1) Absolute (pen) mode: + // The coordinates are scaled to the virtual desktop (by default). The user + // can also choose to scale to the monitor or a region of the screen. + // When entering proximity, the tablet driver snaps the mouse pointer to the + // tablet position scaled to that area and keeps it in sync. + // 2) Relative (mouse) mode: + // The pen follows the mouse. The constant 'absoluteRange' specifies the + // manhattanLength difference for detecting if a tablet input device is in this mode, + // in which case we snap the position to the mouse position. + // It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext + // area is always the virtual desktop. + enum { absoluteRange = 20 }; const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry(); if (QWindowsContext::verboseTablet) @@ -409,10 +420,24 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() const PACKET &packet = localPacketBuf[i]; const int z = currentDevice == QTabletEvent::FourDMouse ? int(packet.pkZ) : 0; - const QPointF globalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea); + + // This code is to delay the tablet data one cycle to sync with the mouse location. + QPointF globalPosF = m_oldGlobalPosF; + m_oldGlobalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea); QWindow *target = QGuiApplicationPrivate::tabletPressTarget; // Pass to window that grabbed it. - const QPoint globalPos = globalPosF.toPoint(); + QPoint globalPos = globalPosF.toPoint(); + + // Get Mouse Position and compare to tablet info + const QPoint mouseLocation = QWindowsCursor::mousePosition(); + + // Positions should be almost the same if we are in absolute + // mode. If they are not, use the mouse location. + if ((mouseLocation - globalPos).manhattanLength() > absoluteRange) { + globalPos = mouseLocation; + globalPosF = globalPos; + } + if (!target) if (QPlatformWindow *pw = QWindowsContext::instance()->findPlatformWindowAt(GetDesktopWindow(), globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT)) target = pw->window(); diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h index 12f96b618d..5e29cd9554 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h @@ -134,6 +134,7 @@ private: bool m_tiltSupport; QVector<QWindowsTabletDeviceData> m_devices; int m_currentDevice; + QPointF m_oldGlobalPosF; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index be739d0551..1909e0313b 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1056,9 +1056,10 @@ void QWindowsWindow::setVisible(bool visible) // When the window is layered, we won't get WM_PAINT, and "we" are in control // over the rendering of the window // There is nobody waiting for this, so we don't need to flush afterwards. - QWindow *w = window(); - if (w->format().hasAlpha() || qFuzzyCompare(w->opacity(), qreal(1))) + if (isLayered()) { + QWindow *w = window(); fireExpose(QRect(0, 0, w->width(), w->height())); + } } else { if (hasMouseCapture()) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 4961e0377c..d18693f6b8 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -835,7 +835,7 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event) void QXcbDrag::handleStatus(const xcb_client_message_event_t *event) { - if (event->window != connection()->clipboard()->owner()) + if (event->window != connection()->clipboard()->owner() || !drag()) return; xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event); diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp index a3d6a65695..8c10b134bd 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp @@ -48,6 +48,7 @@ #include <qplatformdefs.h> #include <qsocketnotifier.h> #include <X11/SM/SMlib.h> +#include <errno.h> // ERANGE #include <cerrno> // ERANGE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 6d986ba601..aa53093868 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1148,7 +1148,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp) QByteArray ba("Qt NET_WM user time window"); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, - m_window, + m_netWmUserTimeWindow, atom(QXcbAtom::_NET_WM_NAME), atom(QXcbAtom::UTF8_STRING), 8, |