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 | |
parent | 109bf980b37fed405c6c1eb14cb9c83ff897e389 (diff) | |
parent | 2e3870fe37d36ccf4bd84eb90e1d5e08ad00c1bc (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: Ie56539b2e0be611a363b5f15ae5412a78d6945a2
Diffstat (limited to 'src/plugins')
35 files changed, 445 insertions, 326 deletions
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index cbb3092b1d..79a5c82fe0 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -558,37 +558,56 @@ QWidget *QAccessibleCalendarWidget::navigationBar() const #endif // QT_NO_CALENDARWIDGET #ifndef QT_NO_DOCKWIDGET + +// Dock Widget - order of children: +// - Content widget +// - Float button +// - Close button +// If there is a custom title bar widget, that one becomes child 1, after the content 0 +// (in that case the buttons are ignored) QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget) : QAccessibleWidget(widget, QAccessible::Window) { +} +QDockWidgetLayout *QAccessibleDockWidget::dockWidgetLayout() const +{ + return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout()); } -QAccessibleInterface *QAccessibleDockWidget::child(int index) const +int QAccessibleDockWidget::childCount() const { - if (index == 0) { - return new QAccessibleTitleBar(dockWidget()); - } else if (index == 1 && dockWidget()->widget()) { - return QAccessible::queryAccessibleInterface(dockWidget()->widget()); + if (dockWidget()->titleBarWidget()) { + return dockWidget()->widget() ? 2 : 1; } - return 0; + return dockWidgetLayout()->count(); } -int QAccessibleDockWidget::childCount() const +QAccessibleInterface *QAccessibleDockWidget::child(int index) const { - return dockWidget()->widget() ? 2 : 1; + if (dockWidget()->titleBarWidget()) { + if ((!dockWidget()->widget() && index == 0) || (index == 1)) + return QAccessible::queryAccessibleInterface(dockWidget()->titleBarWidget()); + if (index == 0) + return QAccessible::queryAccessibleInterface(dockWidget()->widget()); + } else { + QLayoutItem *item = dockWidgetLayout()->itemAt(index); + if (item) + return QAccessible::queryAccessibleInterface(item->widget()); + } + return 0; } int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const { - if (child) { - if (child->role() == QAccessible::TitleBar) { - return 0; - } else { - return 1; // FIXME - } + if (!child || !child->object() || child->object()->parent() != object()) + return -1; + + if (dockWidget()->titleBarWidget() == child->object()) { + return dockWidget()->widget() ? 1 : 0; } - return -1; + + return dockWidgetLayout()->indexOf(qobject_cast<QWidget*>(child->object())); } QRect QAccessibleDockWidget::rect() const @@ -610,190 +629,13 @@ QDockWidget *QAccessibleDockWidget::dockWidget() const return static_cast<QDockWidget *>(object()); } -//// -// QAccessibleTitleBar -//// -QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget) - : m_dockWidget(widget) -{ - -} - -QAccessibleInterface *QAccessibleTitleBar::parent() const -{ - return new QAccessibleDockWidget(dockWidget()); -} - -QAccessibleInterface *QAccessibleTitleBar::child(int index) const -{ - if (index >= 0) { - QDockWidgetLayout *layout = dockWidgetLayout(); - int role; - int currentIndex = 0; - for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (!w || !w->isVisible()) - continue; - if (currentIndex == index) - return QAccessible::queryAccessibleInterface(w); - ++currentIndex; - } - } - return 0; -} - -int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const -{ - return -1; -} - -int QAccessibleTitleBar::childCount() const -{ - QDockWidgetLayout *layout = dockWidgetLayout(); - int count = 0; - for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (w && w->isVisible()) - ++count; - } - return count; -} - -QString QAccessibleTitleBar::text(QAccessible::Text t) const +QString QAccessibleDockWidget::text(QAccessible::Text t) const { if (t == QAccessible::Name || t == QAccessible::Value) { return qt_accStripAmp(dockWidget()->windowTitle()); } return QString(); } - -QAccessible::State QAccessibleTitleBar::state() const -{ - QAccessible::State state; - - QDockWidget *w = dockWidget(); - if (w->testAttribute(Qt::WA_WState_Visible) == false) - state.invisible = true; - if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow()) - state.focusable = true; - if (w->hasFocus()) - state.focused = true; - if (!w->isEnabled()) - state.disabled = true; - - return state; -} - -QRect QAccessibleTitleBar::rect() const -{ - bool mapToGlobal = true; - QRect rect; - - if (dockWidget()->isFloating()) { - rect = dockWidget()->frameGeometry(); - if (dockWidget()->widget()) { - QPoint globalPos = dockWidget()->mapToGlobal(dockWidget()->widget()->rect().topLeft()); - globalPos.ry()--; - rect.setBottom(globalPos.y()); - mapToGlobal = false; - } - } else { - QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout()); - rect = layout->titleArea(); - } - - if (rect.isNull()) - return rect; - - if (mapToGlobal) - rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft())); - return rect; -} - -QAccessibleInterface *QAccessibleTitleBar::childAt(int x, int y) const -{ - for (int i = 0; i < childCount(); ++i) { - QAccessibleInterface *childIface = child(i); - if (childIface->rect().contains(x,y)) { - return childIface; - } - } - return 0; -} - -QObject *QAccessibleTitleBar::object() const -{ - return 0; -} - -QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const -{ - return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout()); -} - -QDockWidget *QAccessibleTitleBar::dockWidget() const -{ - return m_dockWidget; -} - -//QString QAccessibleTitleBar::actionText(int action, Text t, int child) const -//{ -// QString str; -// if (child >= 1 && child <= childCount()) { -// if (t == Name) { -// switch (action) { -// case Press: -// case DefaultAction: -// if (child == QDockWidgetLayout::CloseButton) { -// str = QDockWidget::tr("Close"); -// } else if (child == QDockWidgetLayout::FloatButton) { -// str = dockWidget()->isFloating() ? QDockWidget::tr("Dock") -// : QDockWidget::tr("Float"); -// } -// break; -// default: -// break; -// } -// } -// } -// return str; -//} - -//bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/) -//{ -// if (!child || !dockWidget()->isEnabled()) -// return false; - -// switch (action) { -// case DefaultAction: -// case Press: { -// QDockWidgetLayout *layout = dockWidgetLayout(); -// QAbstractButton *btn = static_cast<QAbstractButton *>(layout->widgetForRole((QDockWidgetLayout::Role)child)); -// if (btn) -// btn->animateClick(); -// return true; -// break;} -// default: -// break; -// } - -// return false; -//} - -QAccessible::Role QAccessibleTitleBar::role() const -{ - return QAccessible::TitleBar; -} - -void QAccessibleTitleBar::setText(QAccessible::Text /*t*/, const QString &/*text*/) -{ -} - -bool QAccessibleTitleBar::isValid() const -{ - return dockWidget(); -} - #endif // QT_NO_DOCKWIDGET #ifndef QT_NO_CURSOR diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index 3e982e82d6..3f50010685 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -283,31 +283,10 @@ public: int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; int childCount() const Q_DECL_OVERRIDE; QRect rect () const Q_DECL_OVERRIDE; - - QDockWidget *dockWidget() const; -}; - -class QAccessibleTitleBar : public QAccessibleInterface -{ -public: - explicit QAccessibleTitleBar(QDockWidget *widget); - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - QRect rect () const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QObject *object() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - - QPointer<QDockWidget> m_dockWidget; QDockWidget *dockWidget() const; +protected: QDockWidgetLayout *dockWidgetLayout() const; }; diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index e3e614d700..1dac199a09 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -474,16 +474,16 @@ QSize QAccessibleDisplay::imageSize() const } /*! \internal */ -QRect QAccessibleDisplay::imagePosition() const +QPoint QAccessibleDisplay::imagePosition() const { QLabel *label = qobject_cast<QLabel *>(widget()); if (!label) - return QRect(); + return QPoint(); const QPixmap *pixmap = label->pixmap(); if (!pixmap) - return QRect(); + return QPoint(); - return QRect(label->mapToGlobal(label->pos()), label->size()); + return QPoint(label->mapToGlobal(label->pos())); } #ifndef QT_NO_GROUPBOX @@ -605,7 +605,7 @@ QString QAccessibleLineEdit::text(QAccessible::Text t) const break; } if (str.isEmpty()) - str = QAccessibleWidget::text(t);; + str = QAccessibleWidget::text(t); return qt_accStripAmp(str); } diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index 66b4c2bd3e..6024788048 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -110,7 +110,7 @@ public: // QAccessibleImageInterface QString imageDescription() const Q_DECL_OVERRIDE; QSize imageSize() const Q_DECL_OVERRIDE; - QRect imagePosition() const Q_DECL_OVERRIDE; + QPoint imagePosition() const Q_DECL_OVERRIDE; }; #ifndef QT_NO_GROUPBOX diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 4cfc2a6cc4..459a450222 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -55,6 +55,7 @@ #include <xkbcommon_workaround.h> #endif +#include <locale.h> // LC_CTYPE #include <string.h> // strchr, strncmp, etc. #include <strings.h> // strncasecmp #include <clocale> // LC_CTYPE 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, diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp index f41d4f5047..b9f0c394f8 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp +++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp @@ -66,8 +66,7 @@ QCupsPrinterSupport::QCupsPrinterSupport() : QPlatformPrinterSupport(), QCupsPrinterSupport::~QCupsPrinterSupport() { - if (cupsFreeDests) - cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters); + freeCupsPrinters(); } QPrintEngine *QCupsPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode printerMode) @@ -98,14 +97,20 @@ void QCupsPrinterSupport::loadCups() cupsGetOption = (CupsGetOption) m_cups.resolve("cupsGetOption"); } +void QCupsPrinterSupport::freeCupsPrinters() +{ + if (cupsFreeDests && m_cupsPrintersCount) { + cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters); + m_cupsPrintersCount = 0; + m_cupsPrinters = 0; + } +} + void QCupsPrinterSupport::loadCupsPrinters() { - m_cupsPrintersCount = 0; + freeCupsPrinters(); m_printers.clear(); - if (cupsFreeDests) - cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters); - if (cupsGetDests) m_cupsPrintersCount = cupsGetDests(&m_cupsPrinters); @@ -122,6 +127,12 @@ void QCupsPrinterSupport::loadCupsPrinters() } } +QList<QPrinterInfo> QCupsPrinterSupport::availablePrinters() +{ + loadCupsPrinters(); + return QPlatformPrinterSupport::availablePrinters(); +} + QString QCupsPrinterSupport::printerOption(const QPrinterInfo &printer, const QString &key) const { return cupsOption(printerIndex(printer), key); diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h index e9fe24203e..d42c0d2630 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h +++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h @@ -68,12 +68,14 @@ public: virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode); virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const; virtual QList<QPair<QString, QSizeF> > supportedSizesWithNames(const QPrinterInfo &) const; + virtual QList<QPrinterInfo> availablePrinters(); virtual QString printerOption(const QPrinterInfo &printer, const QString &key) const; virtual PrinterOptions printerOptions(const QPrinterInfo &printer) const; private: void loadCups(); void loadCupsPrinters(); + void freeCupsPrinters(); QString cupsOption(int i, const QString &key) const; QLibrary m_cups; diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp index 36e7a3fb8e..2faebf6f64 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp @@ -42,6 +42,7 @@ #include "qwindowsprintersupport.h" #include <QtCore/QList> +#include <QtCore/QScopedArrayPointer> #include <QtPrintSupport/QPrinterInfo> #include <qprintengine_win_p.h> #include <private/qpaintengine_alpha_p.h> @@ -52,25 +53,7 @@ QT_BEGIN_NAMESPACE QWindowsPrinterSupport::QWindowsPrinterSupport() : QPlatformPrinterSupport() { - DWORD needed = 0; - DWORD returned = 0; - if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) { - 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); - QString defaultPrinterName; - QString program; - QString port; - QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, program, port); - for (uint i = 0; i < returned; ++i) { - QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); - bool isDefault = (printerName == defaultPrinterName); - QPrinterInfo printerInfo = createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i); - m_printers.append(printerInfo); - } - } - delete [] buffer; - } + m_printers = QWindowsPrinterSupport::queryPrinters(); } QWindowsPrinterSupport::~QWindowsPrinterSupport() @@ -98,4 +81,35 @@ QList<QPair<QString, QSizeF> >QWindowsPrinterSupport::supportedSizesWithNames(co return QWin32PrintEngine::supportedSizesWithNames(printerInfo); } +QList<QPrinterInfo> QWindowsPrinterSupport::availablePrinters() +{ + m_printers = QWindowsPrinterSupport::queryPrinters(); + return QPlatformPrinterSupport::availablePrinters(); +} + +QList<QPrinterInfo> QWindowsPrinterSupport::queryPrinters() +{ + QList<QPrinterInfo> result; + DWORD needed = 0; + DWORD returned = 0; + if ((!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + || !needed) { + return result; + } + QScopedArrayPointer<BYTE> buffer(new BYTE[needed]); + if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer.data(), needed, &needed, &returned)) + return result; + PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer.data()); + QString defaultPrinterName; + QString program; + QString port; + QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, program, port); + for (uint i = 0; i < returned; ++i) { + const QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); + const bool isDefault = (printerName == defaultPrinterName); + result.append(QPlatformPrinterSupport::createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i)); + } + return result; +} + QT_END_NAMESPACE diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h index 1d5a4f3da4..1b1b1fa215 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.h +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h @@ -58,6 +58,10 @@ public: virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode); virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const; virtual QList<QPair<QString, QSizeF> >supportedSizesWithNames(const QPrinterInfo &printerInfo) const; + virtual QList<QPrinterInfo> availablePrinters(); + +private: + static QList<QPrinterInfo> queryPrinters(); }; QT_END_NAMESPACE |