summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h1
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro3
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm10
-rw-r--r--src/plugins/platforms/ios/quiview.mm29
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplugin.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp168
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h18
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp111
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h10
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h4
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp14
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h2
17 files changed, 234 insertions, 171 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index e754855e7f..a3541829c6 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -99,6 +99,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification;
- (void)viewDidHide;
- (void)viewDidUnhide;
+- (void)removeFromSuperview;
- (BOOL)isFlipped;
- (BOOL)acceptsFirstResponder;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 17d73dc926..528e6f120f 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -497,6 +497,12 @@ QT_WARNING_POP
m_platformWindow->exposeWindow();
}
+- (void)removeFromSuperview
+{
+ QMacAutoReleasePool pool;
+ [super removeFromSuperview];
+}
+
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
{
m_backingStore = backingStore;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro
index 98797e2106..2026b6a6c6 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro
@@ -12,6 +12,9 @@ CONFIG += egl
LIBS += -lbcm_host
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
+# Avoid X11 header collision
+DEFINES += MESA_EGL_NO_X11_HEADERS
+
SOURCES += $$PWD/qeglfsbrcmmain.cpp \
$$PWD/qeglfsbrcmintegration.cpp
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index eaff0daf19..0e3da8dce8 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -89,10 +89,11 @@ QIOSIntegration::QIOSIntegration()
// Set current directory to app bundle folder
QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
+ UIScreen *mainScreen = [UIScreen mainScreen];
NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease];
- if (![screens containsObject:[UIScreen mainScreen]]) {
+ if (![screens containsObject:mainScreen]) {
// Fallback for iOS 7.1 (QTBUG-42345)
- [screens insertObject:[UIScreen mainScreen] atIndex:0];
+ [screens insertObject:mainScreen atIndex:0];
}
for (UIScreen *screen in screens)
@@ -103,7 +104,10 @@ QIOSIntegration::QIOSIntegration()
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
- m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition);
+ QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition;
+ if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
+ touchCapabilities |= QTouchDevice::Pressure;
+ m_touchDevice->setCapabilities(touchCapabilities);
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
QMacInternalPasteboardMime::initializeMimeTypes();
}
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index c6ef843b9f..53b3d30327 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -280,6 +280,19 @@
// -------------------------------------------------------------------------
+- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
+{
+ [super traitCollectionDidChange: previousTraitCollection];
+
+ QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice();
+ QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities();
+ if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
+ touchCapabilities |= QTouchDevice::Pressure;
+ else
+ touchCapabilities &= ~QTouchDevice::Pressure;
+ touchDevice->setCapabilities(touchCapabilities);
+}
+
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput)
@@ -289,6 +302,8 @@
- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state
{
+ bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QTouchDevice::Pressure;
+
foreach (UITouch *uiTouch, m_activeTouches.keys()) {
QWindowSystemInterface::TouchPoint &touchPoint = m_activeTouches[uiTouch];
if (![touches containsObject:uiTouch]) {
@@ -309,9 +324,17 @@
touchPoint.normalPosition = QPointF(globalScreenPosition.x() / screenSize.width(),
globalScreenPosition.y() / screenSize.height());
- // We don't claim that our touch device supports QTouchDevice::Pressure,
- // but fill in a meaningfull value in case clients use it anyways.
- touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0;
+ if (supportsPressure) {
+ // Note: iOS will deliver touchesBegan with a touch force of 0, which
+ // we will reflect/propagate as a 0 pressure, but there is no clear
+ // alternative, as we don't want to wait for a touchedMoved before
+ // sending a touch press event to Qt, just to have a valid pressure.
+ touchPoint.pressure = uiTouch.force / uiTouch.maximumPossibleForce;
+ } else {
+ // We don't claim that our touch device supports QTouchDevice::Pressure,
+ // but fill in a meaningfull value in case clients use it anyways.
+ touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0;
+ }
}
}
}
diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.cpp b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
index 43d913f8d2..203a1cbfd8 100644
--- a/src/plugins/platforms/mirclient/qmirclientplugin.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
@@ -49,11 +49,6 @@ QPlatformIntegration* QMirClientIntegrationPlugin::create(const QString &system,
const QStringList &)
{
if (system.toLower() == "mirclient") {
-#ifdef PLATFORM_API_TOUCH
- setenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient", 1);
-#else
- setenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient", 1);
-#endif
return new QMirClientClientIntegration;
} else {
return 0;
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 800b79347c..c769eb04a4 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -43,15 +43,17 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/private/qguiapplication_p.h> // getPixmapCursor()
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/QDebug>
#include <QtCore/QScopedArrayPointer>
-static void initResources()
+static bool initResources()
{
#if !defined (Q_OS_WINCE) && !defined (QT_NO_IMAGEFORMAT_PNG)
Q_INIT_RESOURCE(cursors);
#endif
+ return true;
}
QT_BEGIN_NAMESPACE
@@ -92,9 +94,14 @@ QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c)
\sa QWindowsWindowCursor
*/
-HCURSOR QWindowsCursor::createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot)
+HCURSOR QWindowsCursor::createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor)
{
HCURSOR cur = 0;
+ scaleFactor /= pixmap.devicePixelRatioF();
+ if (!qFuzzyCompare(scaleFactor, 1)) {
+ pixmap = pixmap.scaled((scaleFactor * QSizeF(pixmap.size())).toSize(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
QBitmap mask = pixmap.mask();
if (mask.isNull()) {
mask = QBitmap(pixmap.size());
@@ -202,17 +209,43 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
}
// Create a cursor from image and mask of the format QImage::Format_Mono.
-static HCURSOR createBitmapCursor(const QCursor &cursor)
+static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1)
{
Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap());
- const QImage bbits = cursor.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
- const QImage mbits = cursor.mask()->toImage().convertToFormat(QImage::Format_Mono);
+ QImage bbits = cursor.bitmap()->toImage();
+ QImage mbits = cursor.mask()->toImage();
+ scaleFactor /= bbits.devicePixelRatioF();
+ if (!qFuzzyCompare(scaleFactor, 1)) {
+ const QSize scaledSize = (QSizeF(bbits.size()) * scaleFactor).toSize();
+ bbits = bbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ mbits = mbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+ bbits = bbits.convertToFormat(QImage::Format_Mono);
+ mbits = mbits.convertToFormat(QImage::Format_Mono);
const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm);
}
-static inline QSize systemCursorSize() { return QSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); }
+static QSize systemCursorSize(const QPlatformScreen *screen = Q_NULLPTR)
+{
+ const QSize primaryScreenCursorSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
+ if (screen) {
+ // Correct the size if the DPI value of the screen differs from
+ // that of the primary screen.
+ if (const QScreen *primaryQScreen = QGuiApplication::primaryScreen()) {
+ const QPlatformScreen *primaryScreen = primaryQScreen->handle();
+ if (screen != primaryScreen) {
+ const qreal logicalDpi = screen->logicalDpi().first;
+ const qreal primaryScreenLogicalDpi = primaryScreen->logicalDpi().first;
+ if (!qFuzzyCompare(logicalDpi, primaryScreenLogicalDpi))
+ return (QSizeF(primaryScreenCursorSize) * logicalDpi / primaryScreenLogicalDpi).toSize();
+ }
+ }
+ }
+ return primaryScreenCursorSize;
+}
+
static inline QSize standardCursorSize() { return QSize(32, 32); }
#if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG)
@@ -242,7 +275,8 @@ static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &syst
return QWindowsCursor::PixmapCursor(rawImage, hotSpot);
}
-QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
+QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape,
+ const QPlatformScreen *screen)
{
// Non-standard Windows cursors are created from bitmaps
static const uchar vsplit_bits[] = {
@@ -410,13 +444,13 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor
switch (cursorShape) {
case Qt::SplitVCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, vsplit_bits, vsplitm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, vsplit_bits, vsplitm_bits);
case Qt::SplitHCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, hsplit_bits, hsplitm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, hsplit_bits, hsplitm_bits);
case Qt::OpenHandCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, openhand_bits, openhandm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, openhand_bits, openhandm_bits);
case Qt::ClosedHandCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
case Qt::DragCopyCursor:
return QWindowsCursor::PixmapCursor(QPixmap(copyDragCursorXpmC), QPoint(0, 0));
case Qt::DragMoveCursor:
@@ -436,7 +470,7 @@ struct QWindowsCustomPngCursor {
int hotSpotY;
};
-QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
+QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen)
{
static const QWindowsCustomPngCursor pngCursors[] = {
{ Qt::SplitVCursor, 32, "splitvcursor_32.png", 11, 11 },
@@ -462,14 +496,14 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor
{ Qt::DragLinkCursor, 64, "draglinkcursor_64.png", 0, 0 }
};
- const int cursorSize = GetSystemMetrics(SM_CXCURSOR);
+ const QSize cursorSize = systemCursorSize(screen);
const QWindowsCustomPngCursor *sEnd = pngCursors + sizeof(pngCursors) / sizeof(pngCursors[0]);
const QWindowsCustomPngCursor *bestFit = 0;
int sizeDelta = INT_MAX;
for (const QWindowsCustomPngCursor *s = pngCursors; s < sEnd; ++s) {
if (s->shape != cursorShape)
continue;
- const int currentSizeDelta = qMax(s->size, cursorSize) - qMin(s->size, cursorSize);
+ const int currentSizeDelta = qMax(s->size, cursorSize.width()) - qMin(s->size, cursorSize.width());
if (currentSizeDelta < sizeDelta) {
bestFit = s;
if (currentSizeDelta == 0)
@@ -492,7 +526,7 @@ struct QWindowsStandardCursorMapping {
LPCWSTR resource;
};
-HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
+HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen)
{
Q_ASSERT(cursorShape != Qt::BitmapCursor);
@@ -515,7 +549,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
switch (cursorShape) {
case Qt::BlankCursor: {
- QImage blank = QImage(systemCursorSize(), QImage::Format_Mono);
+ QImage blank = QImage(systemCursorSize(screen), QImage::Format_Mono);
blank.fill(0); // ignore color table
return createBitmapCursor(blank, blank);
}
@@ -526,7 +560,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
case Qt::DragCopyCursor:
case Qt::DragMoveCursor:
case Qt::DragLinkCursor:
- return QWindowsCursor::createPixmapCursor(customCursor(cursorShape));
+ return QWindowsCursor::createPixmapCursor(customCursor(cursorShape, screen));
default:
break;
}
@@ -555,7 +589,7 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
{
StandardCursorCache::Iterator it = m_standardCursorCache.find(shape);
if (it == m_standardCursorCache.end()) {
- if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape))
+ if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape, m_screen))
it = m_standardCursorCache.insert(shape, CursorHandlePtr(new CursorHandle(hc)));
}
return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle);
@@ -582,17 +616,21 @@ CursorHandlePtr QWindowsCursor::pixmapWindowCursor(const QCursor &c)
++it;
}
}
+ const qreal scaleFactor = QHighDpiScaling::factor(m_screen);
const QPixmap pixmap = c.pixmap();
const HCURSOR hc = pixmap.isNull()
- ? createBitmapCursor(c) : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot());
+ ? createBitmapCursor(c, scaleFactor)
+ : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot(), scaleFactor);
it = m_pixmapCursorCache.insert(cacheKey, CursorHandlePtr(new CursorHandle(hc)));
}
return it.value();
}
-QWindowsCursor::QWindowsCursor()
+QWindowsCursor::QWindowsCursor(const QPlatformScreen *screen)
+ : m_screen(screen)
{
- initResources();
+ static const bool dummy = initResources();
+ Q_UNUSED(dummy)
}
/*!
@@ -654,6 +692,94 @@ void QWindowsCursor::setPos(const QPoint &pos)
SetCursorPos(pos.x() , pos.y());
}
+QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const
+{
+ switch (action) {
+ case Qt::CopyAction:
+ if (m_copyDragCursor.isNull())
+ m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor, m_screen).pixmap;
+ return m_copyDragCursor;
+ case Qt::TargetMoveAction:
+ case Qt::MoveAction:
+ if (m_moveDragCursor.isNull())
+ m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor, m_screen).pixmap;
+ return m_moveDragCursor;
+ case Qt::LinkAction:
+ if (m_linkDragCursor.isNull())
+ m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor, m_screen).pixmap;
+ return m_linkDragCursor;
+ default:
+ break;
+ }
+
+ static const char * const ignoreDragCursorXpmC[] = {
+ "24 30 3 1",
+ ". c None",
+ "a c #000000",
+ "X c #FFFFFF",
+ "aa......................",
+ "aXa.....................",
+ "aXXa....................",
+ "aXXXa...................",
+ "aXXXXa..................",
+ "aXXXXXa.................",
+ "aXXXXXXa................",
+ "aXXXXXXXa...............",
+ "aXXXXXXXXa..............",
+ "aXXXXXXXXXa.............",
+ "aXXXXXXaaaa.............",
+ "aXXXaXXa................",
+ "aXXaaXXa................",
+ "aXa..aXXa...............",
+ "aa...aXXa...............",
+ "a.....aXXa..............",
+ "......aXXa.....XXXX.....",
+ ".......aXXa..XXaaaaXX...",
+ ".......aXXa.XaaaaaaaaX..",
+ "........aa.XaaaXXXXaaaX.",
+ "...........XaaaaX..XaaX.",
+ "..........XaaXaaaX..XaaX",
+ "..........XaaXXaaaX.XaaX",
+ "..........XaaX.XaaaXXaaX",
+ "..........XaaX..XaaaXaaX",
+ "...........XaaX..XaaaaX.",
+ "...........XaaaXXXXaaaX.",
+ "............XaaaaaaaaX..",
+ ".............XXaaaaXX...",
+ "...............XXXX....."};
+
+ if (m_ignoreDragCursor.isNull()) {
+#if !defined (Q_OS_WINCE)
+ HCURSOR cursor = LoadCursor(NULL, IDC_NO);
+ ICONINFO iconInfo = {0, 0, 0, 0, 0};
+ GetIconInfo(cursor, &iconInfo);
+ BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
+
+ if (iconInfo.hbmColor
+ && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
+ && bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
+ const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
+ uchar *colorBits = new uchar[colorBitsLength];
+ GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
+ const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
+ bmColor.bmWidthBytes, QImage::Format_ARGB32);
+
+ m_ignoreDragCursor = QPixmap::fromImage(colorImage);
+ delete [] colorBits;
+ } else {
+ m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
+ }
+
+ DeleteObject(iconInfo.hbmMask);
+ DeleteObject(iconInfo.hbmColor);
+ DestroyCursor(cursor);
+#else // !Q_OS_WINCE
+ m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
+#endif // !Q_OS_WINCE
+ }
+ return m_ignoreDragCursor;
+}
+
/*!
\class QWindowsWindowCursor
\brief Per-Window cursor. Contains a QCursor and manages its associated system
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index ac9e87d1fb..e93f779f94 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -96,29 +96,37 @@ public:
QPoint hotSpot;
};
- QWindowsCursor();
+ explicit QWindowsCursor(const QPlatformScreen *screen);
void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE;
QPoint pos() const Q_DECL_OVERRIDE;
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
- static HCURSOR createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot);
- static HCURSOR createPixmapCursor(const PixmapCursor &pc) { return createPixmapCursor(pc.pixmap, pc.hotSpot); }
- static PixmapCursor customCursor(Qt::CursorShape cursorShape);
+ static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1);
+ static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); }
+ static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR);
- static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape);
+ static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR);
static QPoint mousePosition();
static CursorState cursorState();
CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
CursorHandlePtr pixmapWindowCursor(const QCursor &c);
+ QPixmap dragDefaultCursor(Qt::DropAction action) const;
+
private:
typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
+ const QPlatformScreen *const m_screen;
StandardCursorCache m_standardCursorCache;
PixmapCursorCache m_pixmapCursorCache;
+
+ mutable QPixmap m_copyDragCursor;
+ mutable QPixmap m_moveDragCursor;
+ mutable QPixmap m_linkDragCursor;
+ mutable QPixmap m_ignoreDragCursor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 5435c4820a..c68f05b5bb 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -269,13 +269,6 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
}
#endif // !QT_NO_DEBUG_STREAM
-static qreal dragScaleFactor()
-{
- const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
- const QWindowsScreen *screen = screenManager.screenAtDp(QWindowsCursor::mousePosition());
- return screen ? QHighDpiScaling::factor(screen) : qreal(1);
-}
-
/*!
\brief Blend custom pixmap with cursors.
*/
@@ -286,7 +279,17 @@ void QWindowsOleDropSource::createCursors()
const QPixmap pixmap = drag->pixmap();
const bool hasPixmap = !pixmap.isNull();
- const qreal scaleFactor = dragScaleFactor();
+ // Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget.
+
+ qreal scaleFactor = 1;
+ QPlatformCursor *platformCursor = Q_NULLPTR;
+ if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) {
+ scaleFactor = QHighDpiScaling::factor(platformScreen);
+ platformCursor = platformScreen->cursor();
+ }
+ if (!platformCursor && QGuiApplication::primaryScreen())
+ platformCursor = QGuiApplication::primaryScreen()->handle()->cursor();
+
const bool scalePixmap = hasPixmap
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
@@ -304,8 +307,8 @@ void QWindowsOleDropSource::createCursors()
for (int cnum = 0; cnum < actionCount; ++cnum) {
const Qt::DropAction action = actions[cnum];
QPixmap cursorPixmap = drag->dragCursor(action);
- if (cursorPixmap.isNull())
- cursorPixmap = m_drag->defaultCursor(action);
+ if (cursorPixmap.isNull() && platformCursor)
+ cursorPixmap = static_cast<QWindowsCursor *>(platformCursor)->dragDefaultCursor(action);
const qint64 cacheKey = cursorPixmap.cacheKey();
const auto it = m_cursors.find(action);
if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
@@ -704,94 +707,6 @@ IDropTargetHelper* QWindowsDrag::dropHelper() {
return m_cachedDropTargetHelper;
}
-QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
-{
- switch (action) {
- case Qt::CopyAction:
- if (m_copyDragCursor.isNull())
- m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap;
- return m_copyDragCursor;
- case Qt::TargetMoveAction:
- case Qt::MoveAction:
- if (m_moveDragCursor.isNull())
- m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap;
- return m_moveDragCursor;
- case Qt::LinkAction:
- if (m_linkDragCursor.isNull())
- m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap;
- return m_linkDragCursor;
- default:
- break;
- }
-
- static const char * const ignoreDragCursorXpmC[] = {
- "24 30 3 1",
- ". c None",
- "a c #000000",
- "X c #FFFFFF",
- "aa......................",
- "aXa.....................",
- "aXXa....................",
- "aXXXa...................",
- "aXXXXa..................",
- "aXXXXXa.................",
- "aXXXXXXa................",
- "aXXXXXXXa...............",
- "aXXXXXXXXa..............",
- "aXXXXXXXXXa.............",
- "aXXXXXXaaaa.............",
- "aXXXaXXa................",
- "aXXaaXXa................",
- "aXa..aXXa...............",
- "aa...aXXa...............",
- "a.....aXXa..............",
- "......aXXa.....XXXX.....",
- ".......aXXa..XXaaaaXX...",
- ".......aXXa.XaaaaaaaaX..",
- "........aa.XaaaXXXXaaaX.",
- "...........XaaaaX..XaaX.",
- "..........XaaXaaaX..XaaX",
- "..........XaaXXaaaX.XaaX",
- "..........XaaX.XaaaXXaaX",
- "..........XaaX..XaaaXaaX",
- "...........XaaX..XaaaaX.",
- "...........XaaaXXXXaaaX.",
- "............XaaaaaaaaX..",
- ".............XXaaaaXX...",
- "...............XXXX....."};
-
- if (m_ignoreDragCursor.isNull()) {
-#if !defined (Q_OS_WINCE)
- HCURSOR cursor = LoadCursor(NULL, IDC_NO);
- ICONINFO iconInfo = {0, 0, 0, 0, 0};
- GetIconInfo(cursor, &iconInfo);
- BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
-
- if (iconInfo.hbmColor
- && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
- && bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
- const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
- uchar *colorBits = new uchar[colorBitsLength];
- GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
- const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
- bmColor.bmWidthBytes, QImage::Format_ARGB32);
-
- m_ignoreDragCursor = QPixmap::fromImage(colorImage);
- delete [] colorBits;
- } else {
- m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
- }
-
- DeleteObject(iconInfo.hbmMask);
- DeleteObject(iconInfo.hbmColor);
- DestroyCursor(cursor);
-#else // !Q_OS_WINCE
- m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
-#endif // !Q_OS_WINCE
- }
- return m_ignoreDragCursor;
-}
-
Qt::DropAction QWindowsDrag::drag(QDrag *drag)
{
// TODO: Accessibility handling?
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index b031faa884..ebe949a6af 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -42,6 +42,9 @@
struct IDropTargetHelper;
QT_BEGIN_NAMESPACE
+
+class QPlatformScreen;
+
class QWindowsDropMimeData : public QWindowsInternalMimeData {
public:
QWindowsDropMimeData() {}
@@ -97,8 +100,6 @@ public:
IDropTargetHelper* dropHelper();
- QPixmap defaultCursor(Qt::DropAction action) const;
-
private:
static bool m_canceled;
@@ -106,11 +107,6 @@ private:
IDataObject *m_dropDataObject;
IDropTargetHelper* m_cachedDropTargetHelper;
-
- mutable QPixmap m_copyDragCursor;
- mutable QPixmap m_moveDragCursor;
- mutable QPixmap m_linkDragCursor;
- mutable QPixmap m_ignoreDragCursor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index de4ef79b81..e69665e4a9 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -195,16 +195,6 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d)
}
#endif // !QT_NO_DEBUG_STREAM
-// Return the cursor to be shared by all screens (virtual desktop).
-static inline QSharedPointer<QPlatformCursor> sharedCursor()
-{
-#ifndef QT_NO_CURSOR
- if (const QScreen *primaryScreen = QGuiApplication::primaryScreen())
- return static_cast<const QWindowsScreen *>(primaryScreen->handle())->cursorPtr();
-#endif
- return QSharedPointer<QPlatformCursor>(new QWindowsCursor);
-}
-
/*!
\class QWindowsScreen
\brief Windows screen.
@@ -216,7 +206,7 @@ static inline QSharedPointer<QPlatformCursor> sharedCursor()
QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
m_data(data)
#ifndef QT_NO_CURSOR
- ,m_cursor(sharedCursor())
+ , m_cursor(new QWindowsCursor(this))
#endif
{
}
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index bc8fbf553b..879cda047e 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -42,7 +42,7 @@
#include <QtCore/QList>
#include <QtCore/QVector>
#include <QtCore/QPair>
-#include <QtCore/QSharedPointer>
+#include <QtCore/QScopedPointer>
#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
@@ -74,7 +74,7 @@ class QWindowsScreen : public QPlatformScreen
{
public:
#ifndef QT_NO_CURSOR
- typedef QSharedPointer<QPlatformCursor> CursorPtr;
+ typedef QScopedPointer<QPlatformCursor> CursorPtr;
#endif
explicit QWindowsScreen(const QWindowsScreenData &data);
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 158917184c..a642443386 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -507,6 +507,8 @@ QWinRTScreen::QWinRTScreen()
hr = d->displayInformation->get_NativeOrientation(&displayOrientation);
Q_ASSERT_SUCCEEDED(hr);
d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+ // Set initial pixel density
+ onDpiChanged(Q_NULLPTR, Q_NULLPTR);
d->orientation = d->nativeOrientation;
ComPtr<IApplicationViewStatics2> applicationViewStatics;
@@ -753,7 +755,6 @@ void QWinRTScreen::initialize()
Q_ASSERT_SUCCEEDED(hr);
hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]);
Q_ASSERT_SUCCEEDED(hr);
- onDpiChanged(Q_NULLPTR, Q_NULLPTR);
onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
onVisibilityChanged(nullptr, nullptr);
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 901764bbf8..50d49ca798 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1086,8 +1086,12 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
case XCB_FOCUS_OUT:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
case XCB_KEY_PRESS:
- m_keyboard->updateXKBStateFromCore(((xcb_key_press_event_t *)event)->state);
+ {
+ xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
+ m_keyboard->updateXKBStateFromCore(kp->state);
+ setTime(kp->time);
HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
+ }
case XCB_KEY_RELEASE:
m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 55bae05523..db7d837e01 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -556,7 +556,8 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode)
for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) {
xcb_randr_mode_info_t *modeInfo = modesIter.data;
if (modeInfo->id == mode) {
- m_refreshRate = modeInfo->dot_clock / (modeInfo->htotal * modeInfo->vtotal);
+ const uint32_t dotCount = modeInfo->htotal * modeInfo->vtotal;
+ m_refreshRate = (dotCount != 0) ? modeInfo->dot_clock / dotCount : 0;
m_mode = mode;
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 5d052a7ca1..4bd4639833 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -314,8 +314,6 @@ void QXcbWindow::create()
destroy();
- m_deferredExpose = false;
- m_configureNotifyPending = true;
m_windowState = Qt::WindowNoState;
Qt::WindowType type = window()->type();
@@ -2032,12 +2030,8 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
if (newScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
- m_configureNotifyPending = false;
-
- if (m_deferredExpose) {
- m_deferredExpose = false;
+ if (m_mapped)
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
- }
if (m_usingSyncProtocol && m_syncState == SyncReceived)
m_syncState = SyncAndConfigureReceived;
@@ -2104,10 +2098,8 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
m_mapped = true;
if (m_deferredActivation)
requestActivateWindow();
- if (m_configureNotifyPending)
- m_deferredExpose = true;
- else
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
+
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 1a8e031779..c42c98c205 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -232,8 +232,6 @@ protected:
bool m_transparent;
bool m_usingSyncProtocol;
bool m_deferredActivation;
- bool m_deferredExpose;
- bool m_configureNotifyPending;
bool m_embedded;
bool m_alertState;
xcb_window_t m_netWmUserTimeWindow;