diff options
author | Liang Qi <liang.qi@qt.io> | 2018-08-07 18:12:02 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2018-08-07 18:12:02 +0000 |
commit | ee2e38490d51667e878ed1732df387a6d9f2a5fe (patch) | |
tree | 4f3b02ab7220326d918b199d60fb33fc497d6dac /src/plugins/platforms | |
parent | 491e427bb2d3cafccbb26d2ca3b7e128d786a564 (diff) | |
parent | 053e7cce79d4bef99ec85101b0d22bbb171072c5 (diff) |
Merge "Merge remote-tracking branch 'origin/5.11' into dev" into refs/staging/dev
Diffstat (limited to 'src/plugins/platforms')
10 files changed, 57 insertions, 142 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 345b370826..5610c36ea1 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -213,26 +213,23 @@ Q_ASSERT(mainMenu); #endif // Grab the app menu out of the current menu. - const int numItems = mainMenu.numberOfItems; - NSMenuItem *oldAppMenuItem = nil; - for (int i = 0; i < numItems; ++i) { - NSMenuItem *item = [mainMenu itemAtIndex:i]; - if (item.submenu == appMenu) { - oldAppMenuItem = item; - [oldAppMenuItem retain]; - [mainMenu removeItemAtIndex:i]; - break; + auto unparentAppMenu = ^bool (NSMenu *supermenu) { + auto index = [supermenu indexOfItemWithSubmenu:appMenu]; + if (index != -1) { + [supermenu removeItemAtIndex:index]; + return true; } - } + return false; + }; - if (oldAppMenuItem) { - oldAppMenuItem.submenu = nil; - [oldAppMenuItem release]; - NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" - action:nil keyEquivalent:@""]; - appMenuItem.submenu = appMenu; - [menu insertItem:appMenuItem atIndex:0]; - } + if (!mainMenu || !unparentAppMenu(mainMenu)) + if (appMenu.supermenu) + unparentAppMenu(appMenu.supermenu); + + NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" + action:nil keyEquivalent:@""]; + appMenuItem.submenu = appMenu; + [menu insertItem:appMenuItem atIndex:0]; } - (NSMenu *)menu diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 1443e5e920..825602e7dc 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -550,6 +550,7 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) } HCURSOR QWindowsCursor::m_overriddenCursor = nullptr; +HCURSOR QWindowsCursor::m_overrideCursor = nullptr; /*! \brief Return cached pixmap cursor or create new one. @@ -622,11 +623,20 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window) } } +// QTBUG-69637: Override cursors can get reset externally when moving across +// window borders. Enforce the cursor again (to be called from enter event). +void QWindowsCursor::enforceOverrideCursor() +{ + if (hasOverrideCursor() && m_overrideCursor != GetCursor()) + SetCursor(m_overrideCursor); +} + void QWindowsCursor::setOverrideCursor(const QCursor &cursor) { const CursorHandlePtr wcursor = cursorHandle(cursor); - if (wcursor->handle()) { - const HCURSOR previousCursor = SetCursor(wcursor->handle()); + if (const auto overrideCursor = wcursor->handle()) { + m_overrideCursor = overrideCursor; + const HCURSOR previousCursor = SetCursor(overrideCursor); if (m_overriddenCursor == nullptr) m_overriddenCursor = previousCursor; } else { @@ -639,7 +649,7 @@ void QWindowsCursor::clearOverrideCursor() { if (m_overriddenCursor) { SetCursor(m_overriddenCursor); - m_overriddenCursor = nullptr; + m_overriddenCursor = m_overrideCursor = nullptr; } } diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 715533e0af..1816732594 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -107,7 +107,8 @@ public: void changeCursor(QCursor * widgetCursor, QWindow * widget) override; void setOverrideCursor(const QCursor &cursor) override; void clearOverrideCursor() override; - bool hasOverrideCursor() const { return m_overriddenCursor != nullptr; } + static void enforceOverrideCursor(); + static bool hasOverrideCursor() { return m_overriddenCursor != nullptr; } QPoint pos() const override; void setPos(const QPoint &pos) override; @@ -143,6 +144,7 @@ private: mutable QPixmap m_ignoreDragCursor; static HCURSOR m_overriddenCursor; + static HCURSOR m_overrideCursor; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 17fc120b42..45788fec15 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2108,6 +2108,8 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow * HWND desktopHWND = GetDesktopWindow(); platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND); } + if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint)) + windowPos->hwndInsertAfter = HWND_BOTTOM; } if (!qWindow->isTopLevel()) // Implement hasHeightForWidth(). return false; @@ -2454,8 +2456,11 @@ static inline bool applyNewCursor(const QWindow *w) void QWindowsWindow::applyCursor() { - if (static_cast<const QWindowsCursor *>(screen()->cursor())->hasOverrideCursor()) + if (QWindowsCursor::hasOverrideCursor()) { + if (isTopLevel()) + QWindowsCursor::enforceOverrideCursor(); return; + } #ifndef QT_NO_CURSOR if (m_cursor->isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel. if (const QWindow *p = window()->parent()) { diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp index 0ae60ad220..85a931e015 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp @@ -68,21 +68,18 @@ QWindowsUiaAccessibility::~QWindowsUiaAccessibility() // Handles UI Automation window messages. bool QWindowsUiaAccessibility::handleWmGetObject(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult) { - if (lParam == LPARAM(UiaRootObjectId)) { - - // Start handling accessibility internally - QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); - - // Ignoring all requests while starting up / shutting down - if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) - return false; - - if (QWindow *window = QWindowsContext::instance()->findWindow(hwnd)) { - if (QAccessibleInterface *accessible = window->accessibleRoot()) { - QWindowsUiaMainProvider *provider = QWindowsUiaMainProvider::providerForAccessible(accessible); - *lResult = QWindowsUiaWrapper::instance()->returnRawElementProvider(hwnd, wParam, lParam, provider); - return true; - } + // Start handling accessibility internally + QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); + + // Ignoring all requests while starting up / shutting down + if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) + return false; + + if (QWindow *window = QWindowsContext::instance()->findWindow(hwnd)) { + if (QAccessibleInterface *accessible = window->accessibleRoot()) { + QWindowsUiaMainProvider *provider = QWindowsUiaMainProvider::providerForAccessible(accessible); + *lResult = QWindowsUiaWrapper::instance()->returnRawElementProvider(hwnd, wParam, lParam, provider); + return true; } } return false; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp index 96f557efd3..11397fb9ec 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp @@ -149,7 +149,7 @@ long roleToControlTypeId(QAccessible::Role role) {QAccessible::Caret, UIA_CustomControlTypeId}, {QAccessible::AlertMessage, UIA_CustomControlTypeId}, {QAccessible::Window, UIA_WindowControlTypeId}, - {QAccessible::Client, UIA_CustomControlTypeId}, + {QAccessible::Client, UIA_GroupControlTypeId}, {QAccessible::PopupMenu, UIA_MenuControlTypeId}, {QAccessible::MenuItem, UIA_MenuItemControlTypeId}, {QAccessible::ToolTip, UIA_ToolTipControlTypeId}, diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 327811a7d2..c14f3f3703 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1693,10 +1693,8 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, continue; if (isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) { auto *touchUpdateNextEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(next); - if (id == touchUpdateNextEvent->detail % INT_MAX && - touchUpdateNextEvent->deviceid == touchUpdateEvent->deviceid) { + if (id == touchUpdateNextEvent->detail % INT_MAX) return true; - } } } return false; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index c24bcf91f3..0b31e9c3e7 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -569,7 +569,6 @@ private: bool m_xi2Enabled = false; #if QT_CONFIG(xcb_xinput) - QVector<int> m_floatingSlaveDevices; int m_xi2Minor = -1; void initializeXInput2(); void xi2SetupDevice(void *info, bool removeExisting = true); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 01b1b37bb8..a327d8dea7 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -113,7 +113,7 @@ void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window) } qt_xcb_input_event_mask_t mask; - mask.header.deviceid = XCB_INPUT_DEVICE_ALL; + mask.header.deviceid = XCB_INPUT_DEVICE_ALL_MASTER; mask.header.mask_len = 1; mask.mask = bitMask; xcb_void_cookie_t cookie = @@ -309,7 +309,6 @@ void QXcbConnection::xi2SetupDevices() m_scrollingDevices.clear(); m_touchDevices.clear(); m_xiMasterPointerIds.clear(); - m_floatingSlaveDevices.clear(); auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, m_connection, XCB_INPUT_DEVICE_ALL); if (!reply) { @@ -320,10 +319,6 @@ void QXcbConnection::xi2SetupDevices() auto it = xcb_input_xi_query_device_infos_iterator(reply.get()); for (; it.rem; xcb_input_xi_device_info_next(&it)) { xcb_input_xi_device_info_t *deviceInfo = it.data; - if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_FLOATING_SLAVE) { - m_floatingSlaveDevices.append(deviceInfo->deviceid); - continue; - } if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_MASTER_POINTER) { m_xiMasterPointerIds.append(deviceInfo->deviceid); continue; @@ -547,72 +542,6 @@ static inline qreal fixed1616ToReal(xcb_input_fp1616_t val) } #endif // QT_CONFIG(tabletevent) -namespace { - -/*! \internal - - Qt listens for XIAllDevices to avoid losing mouse events. This function - ensures that we don't process the same event twice: from a slave device and - then again from a master device. - - In a normal use case (e.g. mouse press and release inside a window), we will - drop events from master devices as duplicates. Other advantage of processing - events from slave devices is that they don't share button state. All buttons - on a master device share the state. - - Examples of special cases: - - - During system move/resize, window manager (_NET_WM_MOVERESIZE) grabs the - master pointer, in this case we process the matching release from the slave - device. A master device event is not sent by the server, hence no duplicate - event to drop. If we listened for XIAllMasterDevices instead, we would never - see a release event in this case. - - - If we dismiss a context menu by clicking somewhere outside a Qt application, - we will process the mouse press from the master pointer as that is the - device we are grabbing. We are not grabbing slave devices (grabbing on the - slave device is buggy according to 19d289ab1b5bde3e136765e5432b5c7d004df3a4). - And since the event occurs outside our window, the slave device event is - not sent to us by the server, hence no duplicate event to drop. -*/ -bool isDuplicateEvent(xcb_ge_event_t *event) -{ - struct qXIEvent { - bool isValid = false; - uint16_t sourceid; - uint8_t event_type; - uint32_t detail; - int32_t root_x; - int32_t root_y; - }; - static qXIEvent lastSeenEvent; - - bool isDuplicate = false; - auto xiDeviceEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event); - if (lastSeenEvent.isValid) { - isDuplicate = lastSeenEvent.sourceid == xiDeviceEvent->sourceid && - lastSeenEvent.event_type == xiDeviceEvent->event_type && - lastSeenEvent.detail == xiDeviceEvent->detail && - lastSeenEvent.root_x == xiDeviceEvent->root_x && - lastSeenEvent.root_y == xiDeviceEvent->root_y; - } else { - lastSeenEvent.isValid = true; - } - lastSeenEvent.sourceid = xiDeviceEvent->sourceid; - lastSeenEvent.event_type = xiDeviceEvent->event_type; - lastSeenEvent.detail = xiDeviceEvent->detail; - lastSeenEvent.root_x = xiDeviceEvent->root_x; - lastSeenEvent.root_y = xiDeviceEvent->root_y; - - if (isDuplicate) - // This sanity check ensures that special cases like QTBUG-59277 keep working. - lastSeenEvent.isValid = false; // An event can be a duplicate only once. - - return isDuplicate; -} - -} // namespace - void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { auto *xiEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event); @@ -621,31 +550,15 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) xcb_input_enter_event_t *xiEnterEvent = nullptr; QXcbWindowEventListener *eventListener = 0; - bool isTouchEvent = true; switch (xiEvent->event_type) { case XCB_INPUT_BUTTON_PRESS: case XCB_INPUT_BUTTON_RELEASE: case XCB_INPUT_MOTION: - isTouchEvent = false; - if (!xi2MouseEventsDisabled() && isDuplicateEvent(event)) - return; case XCB_INPUT_TOUCH_BEGIN: case XCB_INPUT_TOUCH_UPDATE: case XCB_INPUT_TOUCH_END: { xiDeviceEvent = xiEvent; - - if (m_floatingSlaveDevices.contains(xiDeviceEvent->sourceid)) - return; // Not interested in floating slave device events, only in attached slaves. - - bool isSlaveEvent = xiDeviceEvent->deviceid == xiDeviceEvent->sourceid; - if (!xi2MouseEventsDisabled() && isTouchEvent && isSlaveEvent) { - // For touch events we want events only from master devices, at least - // currently there is no apparent reason why we would need to consider - // events from slave devices. - return; - } - eventListener = windowEventListenerFromId(xiDeviceEvent->event); sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master break; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index ed37c6b1f8..d42d95f890 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2569,12 +2569,13 @@ bool QXcbWindow::startSystemMove(const QPoint &pos) bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) { -#if QT_CONFIG(xcb_xinput) + return false; // ### FIXME QTBUG-69716 const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); if (!connection()->wmSupport()->isSupportedByWM(moveResize)) return false; const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen()); +#if QT_CONFIG(xcb_xinput) // ### FIXME QTBUG-53389 bool startedByTouch = connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner); if (startedByTouch) { @@ -2584,11 +2585,9 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) return false; } // KWin, Openbox, AwesomeWM have been tested to work with _NET_WM_MOVERESIZE. - } else { // Started by mouse press. - if (!connection()->hasXInput2() || connection()->xi2MouseEventsDisabled()) { - // Without XI2 we can't get button press/move/release events. - return false; - } + } else +#endif + { // Started by mouse press. if (connection()->isUnity()) return false; // _NET_WM_MOVERESIZE on this WM is bouncy (WM bug?). @@ -2596,11 +2595,6 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) } return true; -#else - Q_UNUSED(pos); - Q_UNUSED(corner); - return false; -#endif // xcb_xinput } void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner) |