From e6498362fde937259295e9b2ddbe9b59136f47ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 25 Jul 2019 16:06:02 +0200 Subject: macOS: Respect color space set on NSWindow when flushing backingstore By default Qt tries to avoid potentially costly color matching by not assigning an sRGB color space to our backingstore, even if that's what we in practice fill it with. We used to do this by assigning the display's color space, which effectively opts out of color matching, similar to the old behavior of the device RGB color space (which nowadays implies sRGB). By picking up the color space from the NSWindow instead, we allow the user to override the color space to trigger color matching, for example by explicitly setting it to NSColorSpace.sRGBColorSpace. NSWindow will fall back to the screen's color space if the window doesn't have one set. Task-number: QTBUG-47660 Change-Id: Iac8177e85e86fe9044a41eb2c93fbf26bb83c248 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Timur Pocheptsov Reviewed-by: Simon Hausmann --- src/plugins/platforms/cocoa/qcocoabackingstore.h | 11 +++++++-- src/plugins/platforms/cocoa/qcocoabackingstore.mm | 30 ++++++++++++++--------- 2 files changed, 28 insertions(+), 13 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 2398e6351e..9be6814ae7 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -49,7 +49,14 @@ QT_BEGIN_NAMESPACE -class QNSWindowBackingStore : public QRasterBackingStore +class QCocoaBackingStore : public QRasterBackingStore +{ +protected: + QCocoaBackingStore(QWindow *window); + QCFType colorSpace() const; +}; + +class QNSWindowBackingStore : public QCocoaBackingStore { public: QNSWindowBackingStore(QWindow *window); @@ -64,7 +71,7 @@ private: void redrawRoundedBottomCorners(CGRect) const; }; -class QCALayerBackingStore : public QPlatformBackingStore +class QCALayerBackingStore : public QCocoaBackingStore { public: QCALayerBackingStore(QWindow *window); diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 78aa98094c..af50aabe15 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -48,11 +48,24 @@ QT_BEGIN_NAMESPACE -QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window) +QCocoaBackingStore::QCocoaBackingStore(QWindow *window) : QRasterBackingStore(window) { } +QCFType QCocoaBackingStore::colorSpace() const +{ + NSView *view = static_cast(window()->handle())->view(); + return QCFType::constructFromGet(view.window.colorSpace.CGColorSpace); +} + +// ---------------------------------------------------------------------------- + +QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window) + : QCocoaBackingStore(window) +{ +} + QNSWindowBackingStore::~QNSWindowBackingStore() { } @@ -175,11 +188,10 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion ®ion, const Q_ASSERT_X(graphicsContext, "QCocoaBackingStore", "Focusing the view should give us a current graphics context"); - // Prevent potentially costly color conversion by assigning the display color space - // to the backingstore image. This does not copy the underlying image data. - CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace; + // Tag backingstore image with color space based on the window. + // Note: This does not copy the underlying image data. QCFType cgImage = CGImageCreateCopyWithColorSpace( - QCFType(m_image.toCGImage()), displayColorSpace); + QCFType(m_image.toCGImage()), colorSpace()); // Create temporary image to use for blitting, without copying image data NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease]; @@ -305,7 +317,7 @@ template constexpr backwards_t backwards(R&& r) { return {std::forward(r)}; } QCALayerBackingStore::QCALayerBackingStore(QWindow *window) - : QPlatformBackingStore(window) + : QCocoaBackingStore(window) { qCDebug(lcQpaBackingStore) << "Creating QCALayerBackingStore for" << window; m_buffers.resize(1); @@ -444,11 +456,7 @@ bool QCALayerBackingStore::recreateBackBufferIfNeeded() << "based on requested" << m_requestedSize << "and dpr =" << devicePixelRatio; static auto pixelFormat = QImage::toPixelFormat(QImage::Format_ARGB32_Premultiplied); - - NSView *view = static_cast(window()->handle())->view(); - auto colorSpace = QCFType::constructFromGet(view.window.screen.colorSpace.CGColorSpace); - - m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace)); + m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace())); return true; } -- cgit v1.2.3 From 7138d6fd6bba2c2e55d02bccf7fd0c6c287eab29 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 22 Jul 2019 15:50:49 +0200 Subject: QWinRTFileEngine: Implement setSize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-77132 Change-Id: Ic0410297a2215f1b7b656966cbe84b925706532f Reviewed-by: AndrĂ© de la Rocha Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/winrt/qwinrtfileengine.cpp | 23 +++++++++++++++++++++++ src/plugins/platforms/winrt/qwinrtfileengine.h | 1 + 2 files changed, 24 insertions(+) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index 3014b30c38..e9b2a82763 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -257,6 +257,29 @@ qint64 QWinRTFileEngine::size() const return qint64(size); } +bool QWinRTFileEngine::setSize(qint64 size) +{ + Q_D(QWinRTFileEngine); + if (!d->stream) { + setError(QFileDevice::ResizeError, QLatin1String("File must be open to be resized")); + return false; + } + + if (size < 0) { + setError(QFileDevice::ResizeError, QLatin1String("File size cannot be negative")); + return false; + } + + HRESULT hr = d->stream->put_Size(static_cast(size)); + RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ResizeError, false); + if (!flush()) { + setError(QFileDevice::ResizeError, QLatin1String("Could not flush file")); + return false; + } + + return true; +} + qint64 QWinRTFileEngine::pos() const { Q_D(const QWinRTFileEngine); diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.h b/src/plugins/platforms/winrt/qwinrtfileengine.h index 4485917c9e..453565a95a 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.h +++ b/src/plugins/platforms/winrt/qwinrtfileengine.h @@ -79,6 +79,7 @@ public: bool close() override; bool flush() override; qint64 size() const override; + bool setSize(qint64 size) override; qint64 pos() const override; bool seek(qint64 pos) override; bool remove() override; -- cgit v1.2.3 From 3fbb6a957227968951283107813271218058b719 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 23 Jul 2019 07:48:46 +0200 Subject: QWinRTFileEngine: Handle QIODevice::Truncate when opening files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-77095 Change-Id: I45b38fab779518c49b22077c493d8640572d40d9 Reviewed-by: AndrĂ© de la Rocha Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/winrt/qwinrtfileengine.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index e9b2a82763..962e4ab938 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -196,7 +197,19 @@ bool QWinRTFileEngine::open(QIODevice::OpenMode openMode) hr = QWinRTFunctions::await(op, d->stream.GetAddressOf()); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false); - d->openMode = openMode; + const ProcessOpenModeResult res = processOpenModeFlags(openMode); + if (!res.ok) { + setError(QFileDevice::OpenError, res.error); + return false; + } + d->openMode = res.openMode; + if (d->openMode & QIODevice::Truncate) { + if (!setSize(0)) { + close(); + setError(QFileDevice::OpenError, QLatin1String("Could not truncate file")); + return false; + } + } return SUCCEEDED(hr); } -- cgit v1.2.3 From c8bb8cb7614768156f9cc4bccc2df928d5430067 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Fri, 26 Jul 2019 18:16:33 +0200 Subject: Windows QPA: Fix detection of the Surface Pen eraser button The Surface Pen eraser button generates Meta+F18/19/20 keystrokes, but when it is not touching the screen the Fn WM_KEYDOWN message is eaten and only a Fn WM_KEYUP message with the previous state as "not pressed" is generated, which would be ignored. With this patch we detect this case and synthesize the expected key events to allow the button to be used in applications. Fixes: QTBUG-77153 Change-Id: I075f5cbb903cb36c9ec241ee1bb31d436b725e3a Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowskeymapper.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index c5af4d8042..da630005d6 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -1301,7 +1301,23 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg, || code == Qt::Key_Control || code == Qt::Key_Meta || code == Qt::Key_Alt)) { - // Someone ate the key down event + + // Workaround for QTBUG-77153: + // The Surface Pen eraser button generates Meta+F18/19/20 keystrokes, + // but when it is not touching the screen the Fn Down is eaten and only + // a Fn Up with the previous state as "not pressed" is generated, which + // would be ignored. We detect this case and synthesize the expected events. + if ((msg.lParam & 0x40000000) == 0 && + Qt::KeyboardModifier(state) == Qt::NoModifier && + ((code == Qt::Key_F18) || (code == Qt::Key_F19) || (code == Qt::Key_F20))) { + QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code, + Qt::MetaModifier, scancode, + quint32(msg.wParam), MetaLeft); + QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code, + Qt::NoModifier, scancode, + quint32(msg.wParam), 0); + result = true; + } } else { if (!code) code = asciiToKeycode(rec->ascii ? char(rec->ascii) : char(msg.wParam), state); -- cgit v1.2.3 From f4647b40ca9319508468ead8144116d0a5718ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 29 Jul 2019 15:13:02 +0200 Subject: macOS: Respect QSurfaceFormat color space when creating NSWindow Task-number: QTBUG-47660 Change-Id: I90a2956bfaa52c361a3eba32f0ea19c0eca8c277 Reviewed-by: Simon Hausmann --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 42b662cfe4..b609fb3995 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1647,6 +1647,9 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) [nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB]; } + if (format().colorSpace() == QSurfaceFormat::sRGBColorSpace) + nsWindow.colorSpace = NSColorSpace.sRGBColorSpace; + return nsWindow; } -- cgit v1.2.3