diff options
author | Liang Qi <liang.qi@qt.io> | 2019-05-13 08:04:58 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2019-05-13 08:04:58 +0200 |
commit | 388fe97f2a54089544dff0ed3af6ca70bf604716 (patch) | |
tree | 163b47974c625849726804337bd667c942dfbc77 /src/plugins/platforms | |
parent | a0c4b6f34546bdd22167a76a0540d37e9a37c0cf (diff) | |
parent | 591116490cf313808e8ba05ddd066656a1d1a566 (diff) |
Merge remote-tracking branch 'origin/5.13' into dev
Conflicts:
src/corelib/tools/qstring.cpp
Change-Id: I81dbf90fc936c9bf08197baefa071117bddb1c63
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 45 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_mouse.mm | 42 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnswindowdelegate.mm | 4 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmfontdatabase.cpp | 8 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmfontdatabase.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmtheme.cpp | 15 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmtheme.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/wasm.pro | 3 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowspointerhandler.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowstabletsupport.cpp | 72 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowstabletsupport.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 4 |
15 files changed, 180 insertions, 29 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 6f24598250..470da63e3d 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -76,8 +76,10 @@ public: void endPaint() override; void flush(QWindow *, const QRegion &, const QPoint &) override; +#ifndef QT_NO_OPENGL void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, QPlatformTextureList *textures, bool translucentBackground) override; +#endif QPlatformGraphicsBuffer *graphicsBuffer() const override; diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index d42a723b47..e786ecb5a5 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -523,6 +523,7 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion, // the window server. } +#ifndef QT_NO_OPENGL void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, QPlatformTextureList *textures, bool translucentBackground) { @@ -531,6 +532,7 @@ void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®io QPlatformBackingStore::composeAndFlush(window, region, offset, textures, translucentBackground); } +#endif QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const { diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 298d11fe08..0d7eab9a94 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1208,23 +1208,34 @@ void QCocoaWindow::windowDidChangeScreen() if (!window()) return; - const bool wasRunningDisplayLink = static_cast<QCocoaScreen *>(screen())->isRunningDisplayLink(); - - if (QCocoaScreen *newScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen)) { - if (newScreen == screen()) { - // Screen properties have changed. Will be handled by - // NSApplicationDidChangeScreenParametersNotification - // in QCocoaIntegration::updateScreens(). - return; - } - - qCDebug(lcQpaWindow) << window() << "moved to" << newScreen; - QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen()); - - if (hasPendingUpdateRequest() && wasRunningDisplayLink) - requestUpdate(); // Restart display-link on new screen - } else { - qCWarning(lcQpaWindow) << "Failed to get QCocoaScreen for" << m_view.window.screen; + // Note: When a window is resized to 0x0 Cocoa will report the window's screen as nil + auto *currentScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen); + auto *previousScreen = static_cast<QCocoaScreen*>(screen()); + + Q_ASSERT_X(!m_view.window.screen || currentScreen, + "QCocoaWindow", "Failed to get QCocoaScreen for NSScreen"); + + // Note: The previous screen may be the same as the current screen, either because + // the screen was just reconfigured, which still results in AppKit sending an + // NSWindowDidChangeScreenNotification, because the previous screen was removed, + // and we ended up calling QWindow::setScreen to move the window, which doesn't + // actually move the window to the new screen, or because we've delivered the + // screen change to the top level window, which will make all the child windows + // of that window report the new screen when requested via QWindow::screen(). + // We still need to deliver the screen change in all these cases, as the + // device-pixel ratio may have changed, and needs to be delivered to all + // windows, both top level and child windows. + + qCDebug(lcQpaWindow) << "Screen changed for" << window() << "from" << previousScreen << "to" << currentScreen; + QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>( + window(), currentScreen ? currentScreen->screen() : nullptr); + + if (currentScreen && hasPendingUpdateRequest()) { + // Restart display-link on new screen. We need to do this unconditionally, + // since we can't rely on the previousScreen reflecting whether or not the + // window actually moved from one screen to another, or just stayed on the + // same screen. + currentScreen->requestUpdate(); } } diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index 0ab09b97d3..4408385aa8 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -147,9 +147,34 @@ ulong timestamp = [theEvent timestamp] * 1000; - auto eventType = cocoaEvent2QtMouseEvent(theEvent); - qCInfo(lcQpaMouse) << "Frame-strut" << eventType << "at" << qtWindowPoint << "with" << m_frameStrutButtons << "in" << self.window; - QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons); + const auto button = cocoaButton2QtButton(theEvent); + auto eventType = [&]() { + switch (theEvent.type) { + case NSEventTypeLeftMouseDown: + case NSEventTypeRightMouseDown: + case NSEventTypeOtherMouseDown: + return QEvent::NonClientAreaMouseButtonPress; + + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseUp: + return QEvent::NonClientAreaMouseButtonRelease; + + case NSEventTypeLeftMouseDragged: + case NSEventTypeRightMouseDragged: + case NSEventTypeOtherMouseDragged: + return QEvent::NonClientAreaMouseMove; + + default: + break; + } + + return QEvent::None; + }(); + + qCInfo(lcQpaMouse) << eventType << "at" << qtWindowPoint << "with" << m_frameStrutButtons << "in" << self.window; + QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), + timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons, button, eventType); } @end @@ -477,12 +502,15 @@ // uses the legacy cursorRect API, so the cursor is reset to the arrow // cursor. See rdar://34183708 - if (self.cursor && self.cursor != NSCursor.currentCursor) { - qCInfo(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor; + auto previousCursor = NSCursor.currentCursor; + + if (self.cursor) [self.cursor set]; - } else { + else [super cursorUpdate:theEvent]; - } + + if (NSCursor.currentCursor != previousCursor) + qCInfo(lcQpaMouse) << "Cursor update for" << self << "resulted in new cursor" << NSCursor.currentCursor; } - (void)mouseMovedImpl:(NSEvent *)theEvent diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index 087cb3651f..9502a315d8 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -51,7 +51,9 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*")); static QCocoaWindow *toPlatformWindow(NSWindow *window) { - return qnsview_cast(window.contentView).platformWindow; + if ([window conformsToProtocol:@protocol(QNSWindowProtocol)]) + return static_cast<QCocoaNSWindow *>(window).platformWindow; + return nullptr; } @implementation QNSWindowDelegate diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp index 0c72dfddc4..dc6bb5847e 100644 --- a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp +++ b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp @@ -38,9 +38,9 @@ void QWasmFontDatabase::populateFontDatabase() // Load font file from resources. Currently // all fonts needs to be bundled with the nexe // as Qt resources. - QStringList fontFileNames = QStringList() << QStringLiteral(":/fonts/Vera.ttf") + QStringList fontFileNames = QStringList() << QStringLiteral(":/fonts/DejaVuSansMono.ttf") + << QStringLiteral(":/fonts/Vera.ttf") << QStringLiteral(":/fonts/DejaVuSans.ttf"); - foreach (const QString &fontFileName, fontFileNames) { QFile theFont(fontFileName); if (!theFont.open(QIODevice::ReadOnly)) @@ -82,5 +82,9 @@ void QWasmFontDatabase::releaseHandle(void *handle) QFreeTypeFontDatabase::releaseHandle(handle); } +QFont QWasmFontDatabase::defaultFont() const +{ + return QFont(QLatin1String("Bitstream Vera Sans")); +} QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.h b/src/plugins/platforms/wasm/qwasmfontdatabase.h index 891f12859e..cbd187a022 100644 --- a/src/plugins/platforms/wasm/qwasmfontdatabase.h +++ b/src/plugins/platforms/wasm/qwasmfontdatabase.h @@ -44,6 +44,7 @@ public: QChar::Script script) const override; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override; void releaseHandle(void *handle) override; + QFont defaultFont() const override; }; QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/wasm/qwasmtheme.cpp b/src/plugins/platforms/wasm/qwasmtheme.cpp index a7f2db3bd3..978d60d686 100644 --- a/src/plugins/platforms/wasm/qwasmtheme.cpp +++ b/src/plugins/platforms/wasm/qwasmtheme.cpp @@ -29,15 +29,22 @@ #include "qwasmtheme.h" #include <QtCore/qvariant.h> +#include <QFontDatabase> QT_BEGIN_NAMESPACE QWasmTheme::QWasmTheme() { + QFontDatabase fdb; + for (auto family : fdb.families()) + if (fdb.isFixedPitch(family)) + fixedFont = new QFont(family); } QWasmTheme::~QWasmTheme() { + if (fixedFont) + delete fixedFont; } QVariant QWasmTheme::themeHint(ThemeHint hint) const @@ -47,4 +54,12 @@ QVariant QWasmTheme::themeHint(ThemeHint hint) const return QPlatformTheme::themeHint(hint); } +const QFont *QWasmTheme::font(Font type) const +{ + if (type == QPlatformTheme::FixedFont) { + return fixedFont; + } + return nullptr; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmtheme.h b/src/plugins/platforms/wasm/qwasmtheme.h index e4cc06e049..7123a1f3d4 100644 --- a/src/plugins/platforms/wasm/qwasmtheme.h +++ b/src/plugins/platforms/wasm/qwasmtheme.h @@ -31,6 +31,7 @@ #define QWASMTHEME_H #include <qpa/qplatformtheme.h> +#include <QtGui/QFont> QT_BEGIN_NAMESPACE @@ -49,6 +50,8 @@ public: ~QWasmTheme(); QVariant themeHint(ThemeHint hint) const override; + const QFont *font(Font type) const override; + QFont *fixedFont = nullptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index 9b98445c68..e8728d9dba 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -39,7 +39,8 @@ HEADERS = \ wasmfonts.files = \ ../../../3rdparty/wasm/Vera.ttf \ - ../../../3rdparty/wasm/DejaVuSans.ttf + ../../../3rdparty/wasm/DejaVuSans.ttf \ + ../../../3rdparty/wasm/DejaVuSansMono.ttf wasmfonts.prefix = /fonts wasmfonts.base = ../../../3rdparty/wasm RESOURCES += wasmfonts diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 7da87a32d5..b730dbcf3b 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -614,6 +614,9 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin if (m_needsEnterOnPointerUpdate) { m_needsEnterOnPointerUpdate = false; if (window != m_currentWindow) { + // make sure we subscribe to leave events for this window + trackLeave(hwnd); + QWindowSystemInterface::handleEnterEvent(window, localPos, globalPos); m_currentWindow = window; if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(target)) diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 84c963af94..cd5a78abb6 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -435,6 +435,27 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L m_currentDevice = m_devices.size(); m_devices.push_back(tabletInit(uniqueId, cursorType)); } + + /** + * We should check button map for changes on every proximity event, not + * only during initialization phase. + * + * WARNING: in 2016 there were some Wacom table drivers, which could mess up + * button mapping if the remapped button was pressed, while the + * application **didn't have input focus**. This bug is somehow + * related to the fact that Wacom drivers allow user to configure + * per-application button-mappings. If the bug shows up again, + * just move this button-map fetching into initialization block. + * + * See https://bugs.kde.org/show_bug.cgi?id=359561 + */ + BYTE logicalButtons[32]; + memset(logicalButtons, 0, 32); + m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_SYSBTNMAP, &logicalButtons); + m_devices[m_currentDevice].buttonsMap[0x1] = logicalButtons[0]; + m_devices[m_currentDevice].buttonsMap[0x2] = logicalButtons[1]; + m_devices[m_currentDevice].buttonsMap[0x4] = logicalButtons[2]; + m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor); m_state = PenProximity; qCDebug(lcQpaTablet) << "enter proximity for device #" @@ -446,6 +467,52 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L return true; } +Qt::MouseButton buttonValueToEnum(DWORD button, + const QWindowsTabletDeviceData &tdd) { + + enum : unsigned { + leftButtonValue = 0x1, + middleButtonValue = 0x2, + rightButtonValue = 0x4, + doubleClickButtonValue = 0x7 + }; + + button = tdd.buttonsMap.value(button); + + return button == leftButtonValue ? Qt::LeftButton : + button == rightButtonValue ? Qt::RightButton : + button == doubleClickButtonValue ? Qt::MiddleButton : + button == middleButtonValue ? Qt::MiddleButton : + button ? Qt::LeftButton /* fallback item */ : + Qt::NoButton; +} + +Qt::MouseButtons convertTabletButtons(DWORD btnNew, + const QWindowsTabletDeviceData &tdd) { + + Qt::MouseButtons buttons = Qt::NoButton; + for (unsigned int i = 0; i < 3; i++) { + unsigned int btn = 0x1 << i; + + if (btn & btnNew) { + Qt::MouseButton convertedButton = + buttonValueToEnum(btn, tdd); + + buttons |= convertedButton; + + /** + * If a button that is present in hardware input is + * mapped to a Qt::NoButton, it means that it is going + * to be eaten by the driver, for example by its + * "Pan/Scroll" feature. Therefore we shouldn't handle + * any of the events associated to it. We'll just return + * Qt::NoButtons here. + */ + } + } + return buttons; +} + bool QWindowsTabletSupport::translateTabletPacketEvent() { static PACKET localPacketBuf[TabletPacketQSize]; // our own tablet packet queue. @@ -552,9 +619,12 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() << tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation; } + Qt::MouseButtons buttons = + convertTabletButtons(packet.pkButtons, m_devices.at(m_currentDevice)); + QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF, currentDevice, currentPointer, - static_cast<Qt::MouseButtons>(packet.pkButtons), + buttons, pressureNew, tiltX, tiltY, tangentialPressure, rotation, z, uniqueId, diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h index d91701d6a5..8f97982308 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h @@ -45,6 +45,7 @@ #include <QtCore/qvector.h> #include <QtCore/qpoint.h> +#include <QtCore/qhash.h> #include <wintab.h> @@ -100,6 +101,7 @@ struct QWindowsTabletDeviceData qint64 uniqueId = 0; int currentDevice = 0; int currentPointerType = 0; + QHash<quint8, quint8> buttonsMap; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index d55545af42..546c976409 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1876,6 +1876,9 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, { if (message == WM_ERASEBKGND) // Backing store - ignored. return true; + // QTBUG-75455: Suppress WM_PAINT sent to invisible windows when setting WS_EX_LAYERED + if (!window()->isVisible() && (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0) + return false; // Ignore invalid update bounding rectangles RECT updateRect; if (!GetUpdateRect(m_data.hwnd, &updateRect, FALSE)) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index e4da207b00..bc09fe2f91 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -240,6 +240,10 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting) } else if (name.contains("uc-logic") && isTablet) { tabletData.pointerType = QTabletEvent::Pen; dbgType = QLatin1String("pen"); + } else if (name.contains("ugee")) { + isTablet = true; + tabletData.pointerType = QTabletEvent::Pen; + dbgType = QLatin1String("pen"); } else { isTablet = false; } |