From 04671a80db32bd7fce470c50934cf60f2e8ffa70 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 15 Jun 2018 23:15:10 +0200 Subject: macOS: Force light theme on macOS 10.14+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until we can properly fix QPalette and QMacStyle, we should disable dark appearance in Qt applications. Disable by setting NSApp.appearance to Aqua, unless dark mode support has been requested via Info.plist or environment variable. Read the NSRequiresAquaSystemAppearance Info.plist key, don’t set NSApp.appearance if its value is false. Also check the QT_MAC_REQUIRES_AQUA_SYSTEM_APPEARANCE environment variable and apply similar logic. You then enable dark mode support by setting: QT_MAC_REQUIRES_AQUA_SYSTEM_APPEARANCE=0 which is slightly awkward, but matches Info.plist behavior. Task-number: QTBUG-68891 Change-Id: I86dc6cf3dee951d46c953396c57d2c31f2e4afcc Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 55b3805df3..79f7ebda54 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -70,6 +70,12 @@ #include +#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) +@interface NSApplication (MojaveForwardDeclarations) +@property (strong) NSAppearance *appearance NS_AVAILABLE_MAC(10_14); +@end +#endif + static void initResources() { Q_INIT_RESOURCE(qcocoaresources); @@ -131,6 +137,21 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) NSApplication *cocoaApplication = [QNSApplication sharedApplication]; qt_redirectNSApplicationSendEvent(); + if (__builtin_available(macOS 10.14, *)) { + // Disable dark appearance, unless the Info.plist or environment requests that it should be enabled + bool plistEnablesDarkAppearance = [[[NSBundle mainBundle] objectForInfoDictionaryKey: + @"NSRequiresAquaSystemAppearance"] boolValue]; + + bool hasEnvironmentRequiresAquaAppearance; + int environmentRequiresAquaAppearance = qEnvironmentVariableIntValue( + "QT_MAC_REQUIRES_AQUA_SYSTEM_APPEARANCE", &hasEnvironmentRequiresAquaAppearance); + bool environmentEnablesDarkAppearance = hasEnvironmentRequiresAquaAppearance + && environmentRequiresAquaAppearance == 0; + + if (!(plistEnablesDarkAppearance || environmentEnablesDarkAppearance)) + NSApp.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; + } + if (qEnvironmentVariableIsEmpty("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM")) { // Applications launched from plain executables (without an app // bundle) are "background" applications that does not take keybaord -- cgit v1.2.3 From 833b9997fd8c93132186d6538770f0c415f73d53 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 27 Jul 2018 12:25:12 +0200 Subject: xcb: make sure we have a valid m_qimage in backing store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch amends a62f1d03560937a306c7586669a46cd9575e9464. If the initial backing store resize request is called with QSize(0, 0), we end up with QXcbBackingStoreImage holding a default contructed QImage / m_qimage. This happens because of the logic in QXcbBackingStoreImage::create(), where if we detect that the requested segmentSize == 0, we do not allocate any memory, and thus don't create a valid image in m_qimage. On subsequent call to QXcbBackingStore::resize() we would only check if QXcbBackingStoreImage object has been created, but not if it is in a valid state. This obviously would cause problems. This patch re-factors the logic to handle better resize to QSize(0, 0). And make the code cleaner by: - merging ::create and ::resize as semantically it is always resize(). - dropping unnecessary argument passing. Task-number: QTBUG-69581 Change-Id: Ied337beb449dea8259fcf6b7d29f0a5bd553019d Reviewed-by: Błażej Szczygieł Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 111 ++++++++++++++----------- 1 file changed, 61 insertions(+), 50 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index b81cb8efa1..8ae9d9899e 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -100,9 +100,7 @@ public: private: void createShmSegment(size_t segmentSize); - void destroyShmSegment(size_t segmentSize); - - void create(const QSize &size, const xcb_format_t *fmt, QImage::Format format); + void destroyShmSegment(); void destroy(bool destroyShm); void ensureGC(xcb_drawable_t dst); @@ -142,6 +140,9 @@ private: bool m_hasAlpha = false; bool m_clientSideScroll = false; + + const xcb_format_t *m_xcb_format = nullptr; + QImage::Format m_qimage_format = QImage::Format_Invalid; }; class QXcbGraphicsBuffer : public QPlatformGraphicsBuffer @@ -183,58 +184,66 @@ QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbBackingStore *backingStore, con : QXcbObject(backingStore->connection()) , m_backingStore(backingStore) { - QXcbWindow *window = static_cast(backingStore->window()->handle()); - const xcb_format_t *fmt = connection()->formatForDepth(window->depth()); - Q_ASSERT(fmt); + auto window = static_cast(m_backingStore->window()->handle()); + m_xcb_format = connection()->formatForDepth(window->depth()); + Q_ASSERT(m_xcb_format); + + m_qimage_format = window->imageFormat(); + m_hasAlpha = QImage::toPixelFormat(m_qimage_format).alphaUsage() == QPixelFormat::UsesAlpha; + if (!m_hasAlpha) + m_qimage_format = qt_maybeAlphaVersionWithSameDepth(m_qimage_format); memset(&m_shm_info, 0, sizeof m_shm_info); - QImage::Format format = window->imageFormat(); - m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; - if (!m_hasAlpha) - create(size, fmt, qt_maybeAlphaVersionWithSameDepth(format)); - else - create(size, fmt, format); + resize(size); } void QXcbBackingStoreImage::resize(const QSize &size) { - xcb_format_t fmt; - fmt.depth = m_xcb_image->depth; - fmt.bits_per_pixel = m_xcb_image->bpp; - fmt.scanline_pad = m_xcb_image->scanline_pad; - memset(fmt.pad0, 0, sizeof(fmt.pad0)); destroy(false); - create(size, &fmt, m_qimage.format()); -} -void QXcbBackingStoreImage::create(const QSize &size, const xcb_format_t *fmt, QImage::Format format) -{ + auto byteOrder = QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST + : XCB_IMAGE_ORDER_LSB_FIRST; m_xcb_image = xcb_image_create(size.width(), size.height(), XCB_IMAGE_FORMAT_Z_PIXMAP, - fmt->scanline_pad, - fmt->depth, fmt->bits_per_pixel, 0, - QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST, + m_xcb_format->scanline_pad, + m_xcb_format->depth, + m_xcb_format->bits_per_pixel, + 0, byteOrder, XCB_IMAGE_ORDER_MSB_FIRST, 0, ~0, 0); const size_t segmentSize = imageDataSize(m_xcb_image); - if (!segmentSize) - return; if (connection()->hasShm()) { - if (m_shm_info.shmaddr && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize)) - destroyShmSegment(m_segmentSize); - if (!m_shm_info.shmaddr) { - qCDebug(lcQpaXcb) << "creating shared memory" << segmentSize << "for" - << size << "depth" << fmt->depth << "bits" << fmt->bits_per_pixel; - createShmSegment(segmentSize); + if (segmentSize == 0) { + if (m_segmentSize > 0) { + destroyShmSegment(); + qCDebug(lcQpaXcb) << "[" << m_backingStore->window() + << "] destroyed SHM segment due to resize to" << size; + } + } else { + // Destroy shared memory segment if it is double (or more) of what we actually + // need with new window size. Or if the new size is bigger than what we currently + // have allocated. + if (m_shm_info.shmaddr && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize)) + destroyShmSegment(); + if (!m_shm_info.shmaddr) { + qCDebug(lcQpaXcb) << "[" << m_backingStore->window() + << "] creating shared memory" << segmentSize << "bytes for" + << size << "depth" << m_xcb_format->depth << "bits" + << m_xcb_format->bits_per_pixel; + createShmSegment(segmentSize); + } } } - m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize); + if (segmentSize == 0) + return; - m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format); + m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize); + m_qimage = QImage(static_cast(m_xcb_image->data), m_xcb_image->width, + m_xcb_image->height, m_xcb_image->stride, m_qimage_format); m_graphics_buffer = new QXcbGraphicsBuffer(&m_qimage); m_xcb_pixmap = xcb_generate_id(xcb_connection()); @@ -248,17 +257,18 @@ void QXcbBackingStoreImage::create(const QSize &size, const xcb_format_t *fmt, Q void QXcbBackingStoreImage::destroy(bool destroyShm) { - if (m_xcb_image->data) { - if (m_shm_info.shmaddr) { - if (destroyShm) - destroyShmSegment(m_segmentSize); - } else { - free(m_xcb_image->data); + if (m_xcb_image) { + if (m_xcb_image->data) { + if (m_shm_info.shmaddr) { + if (destroyShm) + destroyShmSegment(); + } else { + free(m_xcb_image->data); + } } + xcb_image_destroy(m_xcb_image); } - xcb_image_destroy(m_xcb_image); - if (m_gc) { xcb_free_gc(xcb_connection(), m_gc); m_gc = 0; @@ -268,8 +278,12 @@ void QXcbBackingStoreImage::destroy(bool destroyShm) delete m_graphics_buffer; m_graphics_buffer = nullptr; - xcb_free_pixmap(xcb_connection(), m_xcb_pixmap); - m_xcb_pixmap = 0; + if (m_xcb_pixmap) { + xcb_free_pixmap(xcb_connection(), m_xcb_pixmap); + m_xcb_pixmap = 0; + } + + m_qimage = QImage(); } void QXcbBackingStoreImage::flushScrolledRegion(bool clientSideScroll) @@ -412,11 +426,8 @@ bool QXcbBackingStoreImage::createSystemVShmSegment(QXcbConnection *c, size_t se return true; } -void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize) +void QXcbBackingStoreImage::destroyShmSegment() { -#ifndef XCB_USE_SHM_FD - Q_UNUSED(segmentSize) -#endif auto cookie = xcb_shm_detach_checked(xcb_connection(), m_shm_info.shmseg); xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie); if (error) @@ -425,9 +436,9 @@ void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize) #ifdef XCB_USE_SHM_FD if (connection()->hasShmFd()) { - if (munmap(m_shm_info.shmaddr, segmentSize) == -1) { + if (munmap(m_shm_info.shmaddr, m_segmentSize) == -1) { qCWarning(lcQpaXcb, "munmap() failed (%d: %s) for %p with size %zu", - errno, strerror(errno), m_shm_info.shmaddr, segmentSize); + errno, strerror(errno), m_shm_info.shmaddr, m_segmentSize); } } else #endif -- cgit v1.2.3 From f2862b4d5def2c07b8b018532ab74a12b129db2c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 22 May 2018 13:00:38 +0200 Subject: VNC plugin: explicitly cast int to uint16_t before calling htons Otherwise there is a -Werror=narrowing error on big-endian architectures (where htons does nothing). Task-number: QTBUG-68390 Change-Id: Idb204a81aaedb9f4fde1d5fae406da36c7a1953e Reviewed-by: Thiago Macieira (cherry-picked from b206d1c8082a9e01ad3755d311a4cf683ec35161) --- src/plugins/platforms/vnc/qvnc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/vnc/qvnc.cpp b/src/plugins/platforms/vnc/qvnc.cpp index 44fc1c6101..ffe00de2b1 100644 --- a/src/plugins/platforms/vnc/qvnc.cpp +++ b/src/plugins/platforms/vnc/qvnc.cpp @@ -552,9 +552,9 @@ void QVncClientCursor::write(QVncClient *client) const { const quint16 tmp[6] = { htons(0), htons(1), - htons(hotspot.x()), htons(hotspot.y()), - htons(cursor.width()), - htons(cursor.height()) }; + htons(uint16_t(hotspot.x())), htons(uint16_t(hotspot.y())), + htons(uint16_t(cursor.width())), + htons(uint16_t(cursor.height())) }; socket->write((char*)tmp, sizeof(tmp)); const qint32 encoding = qToBigEndian(-239); -- cgit v1.2.3 From 8f1851013363ae22d311881abcb1186949068270 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 14 Aug 2018 07:19:02 +0200 Subject: Silence warning about comparing signed and unsigned qxcbimage.cpp:72:26: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] Task-number: QTBUG-69923 Change-Id: Icdb4ce8cb7ce5b48d7ee3839166eb1c7c9520c78 Reviewed-by: Thiago Macieira --- src/plugins/platforms/xcb/qxcbimage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index e18a08755b..44c7d22344 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -69,7 +69,7 @@ QImage::Format imageFormatForMasks(int depth, int bits_per_pixel, int red_mask, if (red_mask == 0xff && blue_mask == 0xff0000) return QImage::Format_RGBA8888_Premultiplied; #else - if (red_mask == 0xff000000 && blue_mask == 0xff00) + if (unsigned(red_mask) == unsigned(0xff000000) && blue_mask == 0xff00) return QImage::Format_RGBA8888_Premultiplied; #endif if (red_mask == 0x3ff && blue_mask == 0x3ff00000) @@ -90,7 +90,7 @@ QImage::Format imageFormatForMasks(int depth, int bits_per_pixel, int red_mask, if (red_mask == 0xff && blue_mask == 0xff0000) return QImage::Format_RGBX8888; #else - if (red_mask == 0xff000000 && blue_mask == 0xff00) + if (unsigned(red_mask) == unsigned(0xff000000) && blue_mask == 0xff00) return QImage::Format_RGBX8888; #endif break; -- cgit v1.2.3