tdesktop/Telegram/Patches/macold/qtbase_5_3_2.diff

845 lines
36 KiB
Diff

diff --git a/configure b/configure
index cb8d78fd3c..cadb3f0a88 100755
--- a/configure
+++ b/configure
@@ -511,7 +511,8 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then
exit 2
fi
- if ! /usr/bin/xcrun -find xcrun >/dev/null 2>&1; then
+ # Patch: Fix Qt for working with Xcode 8.
+ if ! /usr/bin/xcrun -find xcodebuild >/dev/null 2>&1; then
echo >&2
echo " Xcode not set up properly. You may need to confirm the license" >&2
echo " agreement by running /usr/bin/xcodebuild without arguments." >&2
diff --git a/mkspecs/common/g++-macx.conf b/mkspecs/common/g++-macx.conf
index 086510dd96..078a5ed1dd 100644
--- a/mkspecs/common/g++-macx.conf
+++ b/mkspecs/common/g++-macx.conf
@@ -14,7 +14,13 @@ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -gdwarf-2
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += -gdwarf-2
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO += -g -gdwarf-2
-QMAKE_LFLAGS_STATIC_LIB += -all_load
+# Patch: Don't remember :(
+#QMAKE_LFLAGS_STATIC_LIB += -all_load
+
+# Patch: Use C++14 with custom libc++ build.
+QMAKE_CXXFLAGS_CXX11 = -std=c++1y
+QMAKE_CXXFLAGS += -nostdinc++ -I/usr/local/macold/include/c++/v1
+QMAKE_LFLAGS += /usr/local/macold/lib/libc++.a /usr/local/macold/lib/libc++abi.a -isysroot /
QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvmgcc42
diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf
index 0cc8cd6dfd..ca9725b779 100644
--- a/mkspecs/features/mac/default_pre.prf
+++ b/mkspecs/features/mac/default_pre.prf
@@ -12,7 +12,9 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH) {
error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}. Please use xcode-select to choose Xcode installation path.")
# Make sure Xcode is set up properly
- isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null"))): \
+
+ # Patch: Fix Qt for working with Xcode 8.
+ isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null"))): \
error("Xcode not set up properly. You may need to confirm the license agreement by running /usr/bin/xcodebuild.")
}
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index bb79a139b3..5d595bc3b3 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -220,6 +220,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
int blue_scale = 0;
int alpha_scale = 0;
+ // Patch: Backport a fix for bmp reader.
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
+
if (bi.biSize >= BMP_WIN4 || (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32))) {
if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask))
return false;
@@ -307,8 +311,9 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
image.setDotsPerMeterX(bi.biXPelsPerMeter);
image.setDotsPerMeterY(bi.biYPelsPerMeter);
- if (!d->isSequential())
- d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
+ // Patch: Backport a fix for bmp reader.
+ //if (!d->isSequential())
+ // d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
if (ncols > 0) { // read color table
uchar rgb[4];
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index ebff9509ab..4300ca4c0f 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -87,8 +87,18 @@ public:
if (hasSystemTransform) {
if (systemTransform.type() <= QTransform::TxTranslate)
systemClip.translate(qRound(systemTransform.dx()), qRound(systemTransform.dy()));
- else
+ // Patch: Transform the system clip region back from device pixels to device-independent pixels before
+ // applying systemTransform, which already has transform from device-independent pixels to device pixels.
+ else {
+#ifdef Q_OS_MAC
+ QTransform scaleTransform;
+ const qreal invDevicePixelRatio = 1. / pdev->devicePixelRatio();
+ scaleTransform.scale(invDevicePixelRatio, invDevicePixelRatio);
+ systemClip = systemTransform.map(scaleTransform.map(systemClip));
+#else
systemClip = systemTransform.map(systemClip);
+#endif
+ }
}
// Make sure we're inside the viewport.
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 4879ae51d7..56cdcbaf01 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -654,6 +654,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
while (oldPos < len && !attributes[oldPos].graphemeBoundary)
oldPos++;
} else {
+ // Patch: Skip to the end of the current word, not to the start of the next one.
+ while (oldPos < len && attributes[oldPos].whiteSpace)
+ oldPos++;
if (oldPos < len && d->atWordSeparator(oldPos)) {
oldPos++;
while (oldPos < len && d->atWordSeparator(oldPos))
@@ -662,8 +665,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
while (oldPos < len && !d->atSpace(oldPos) && !d->atWordSeparator(oldPos))
oldPos++;
}
- while (oldPos < len && d->atSpace(oldPos))
- oldPos++;
+ // Patch: Skip to the end of the current word, not to the start of the next one.
+ //while (oldPos < len && d->atSpace(oldPos))
+ // oldPos++;
}
return oldPos;
@@ -1602,6 +1606,9 @@ namespace {
int currentPosition;
glyph_t previousGlyph;
+ // Patch: Backport a crash fix.
+ QFontEngine *previousGlyphFontEngine;
+
QFixed minw;
QFixed softHyphenWidth;
QFixed rightBearing;
@@ -1634,13 +1641,19 @@ namespace {
if (currentPosition > 0 &&
logClusters[currentPosition - 1] < glyphs.numGlyphs) {
previousGlyph = currentGlyph(); // needed to calculate right bearing later
+
+ // Patch: Backport a crash fix.
+ previousGlyphFontEngine = fontEngine;
}
}
- inline void adjustRightBearing(glyph_t glyph)
+ // Patch: Backport a crash fix.
+ inline void adjustRightBearing(QFontEngine *engine, glyph_t glyph)
{
qreal rb;
- fontEngine->getGlyphBearings(glyph, 0, &rb);
+
+ // Patch: Backport a crash fix.
+ engine->getGlyphBearings(glyph, 0, &rb);
rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
}
@@ -1648,13 +1661,16 @@ namespace {
{
if (currentPosition <= 0)
return;
- adjustRightBearing(currentGlyph());
+
+ // Patch: Backport a crash fix.
+ adjustRightBearing(fontEngine, currentGlyph());
}
inline void adjustPreviousRightBearing()
{
if (previousGlyph > 0)
- adjustRightBearing(previousGlyph);
+ // Patch: Backport a crash fix.
+ adjustRightBearing(previousGlyphFontEngine, previousGlyph);
}
inline void resetRightBearing()
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index cbe42c3844..b273db7e78 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -194,6 +194,9 @@ private:
QRectF *brect, int tabstops, int* tabarray, int tabarraylen,
QPainter *painter);
QTextEngine *d;
+
+ // Patch: Give access to the internal api.
+ friend class TextBlock;
};
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 360f9722c7..f28f289ef6 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -118,6 +118,8 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
{
for (int i = 0; i < channelCount; ++i) {
if (channels[i].socket) {
+ // Patch: backport critical bugfix from '4f959b6b30' commit.
+ QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR);
channels[i].socket->close();
delete channels[i].socket;
}
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index ca7afb7d1b..25ae50008d 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -256,6 +256,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
fd->foundryName = QStringLiteral("CoreText");
fd->familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
+
+ // Patch: Fix open sans semibold loading.
+ QCFString _displayName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontDisplayNameAttribute);
+ if (_displayName == QStringLiteral("Open Sans Semibold")) {
+ fd->familyName = _displayName;
+ }
+
fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
fd->weight = QFont::Normal;
fd->style = QFont::StyleNormal;
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 6e2c8a2a9a..3cace8abcb 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -717,7 +717,8 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metric
QFixed QCoreTextFontEngine::emSquareSize() const
{
- return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
+ // Patch: Fix build for Xcode 9.3.1.
+ return QFixed(int(CTFontGetUnitsPerEm(ctfont)));
}
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 92358ecc74..694fee7350 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -213,7 +213,8 @@ static void cleanupCocoaApplicationDelegate()
if (reflectionDelegate) {
if ([reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)])
return [reflectionDelegate applicationShouldTerminate:sender];
- return NSTerminateNow;
+ // Patch: Don't terminate if reflectionDelegate does not respond to that selector, just use the default.
+ //return NSTerminateNow;
}
if ([self canQuit]) {
@@ -289,6 +290,11 @@ static void cleanupCocoaApplicationDelegate()
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
+ // Patch: We need to receive this notification in the delegate as well.
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationDidFinishLaunching:)])
+ [reflectionDelegate applicationDidFinishLaunching:aNotification];
+
Q_UNUSED(aNotification);
inLaunch = false;
// qt_release_apple_event_handler();
@@ -411,7 +417,9 @@ static void cleanupCocoaApplicationDelegate()
{
Q_UNUSED(replyEvent);
NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
- QWindowSystemInterface::handleFileOpenEvent(QUrl(QCFString::toQString(urlString)));
+
+ // Patch: Fix opening of an external url by a protocol handler.
+ QWindowSystemInterface::handleFileOpenEvent(QUrl::fromNSURL([NSURL URLWithString:urlString]));
}
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index b81b9a0b1c..4e59e833b1 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -81,7 +81,7 @@ void QCocoaCursor::setPos(const QPoint &position)
pos.x = position.x();
pos.y = position.y();
- CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0);
+ CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft);
CGEventPost(kCGHIDEventTap, e);
CFRelease(e);
}
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 9850f83dea..b2e1d3dfda 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -649,9 +649,10 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
// Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
OSStatus err = noErr;
- require_action(inContext != NULL, InvalidContext, err = paramErr);
- require_action(inBounds != NULL, InvalidBounds, err = paramErr);
- require_action(inImage != NULL, InvalidImage, err = paramErr);
+ // Patch: Fix build on latest Xcode.
+ //require_action(inContext != NULL, InvalidContext, err = paramErr);
+ //require_action(inBounds != NULL, InvalidBounds, err = paramErr);
+ //require_action(inImage != NULL, InvalidImage, err = paramErr);
CGContextSaveGState( inContext );
CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
@@ -660,9 +661,11 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
CGContextDrawImage(inContext, *inBounds, inImage);
CGContextRestoreGState(inContext);
-InvalidImage:
-InvalidBounds:
-InvalidContext:
+
+// Patch: Fix build on latest Xcode.
+//InvalidImage:
+//InvalidBounds:
+//InvalidContext:
return err;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 9fd05a65ee..dea60720e7 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -402,14 +402,24 @@ void QCocoaIntegration::updateScreens()
}
siblings << screen;
}
+
+ // Patch: Backport crash fix from Qt 5.6.1.
+ // Set virtual siblings list. All screens in mScreens are siblings, because we ignored the
+ // mirrors. Note that some of the screens we update the siblings list for here may be deleted
+ // below, but update anyway to keep the to-be-deleted screens out of the siblings list.
+ foreach (QCocoaScreen* screen, mScreens)
+ screen->setVirtualSiblings(siblings);
+
// Now the leftovers in remainingScreens are no longer current, so we can delete them.
foreach (QCocoaScreen* screen, remainingScreens) {
mScreens.removeOne(screen);
delete screen;
}
+
+ // Patch: Backport crash fix from Qt 5.6.1.
// All screens in mScreens are siblings, because we ignored the mirrors.
- foreach (QCocoaScreen* screen, mScreens)
- screen->setVirtualSiblings(siblings);
+ //foreach (QCocoaScreen* screen, mScreens)
+ // screen->setVirtualSiblings(siblings);
}
QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
index e46eaff6be..c62db534a2 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
@@ -382,6 +382,12 @@ bool QCocoaKeyMapper::updateKeyboard()
keyboardInputLocale = QLocale::c();
keyboardInputDirection = Qt::LeftToRight;
}
+
+ // Patch: Backport a fix for layout-independent keyboard shortcuts.
+ const auto newMode = keyboard_mode;
+ deleteLayouts();
+ keyboard_mode = newMode;
+
return true;
}
@@ -464,7 +470,8 @@ QList<int> QCocoaKeyMapper::possibleKeys(const QKeyEvent *event) const
Qt::KeyboardModifiers neededMods = ModsTbl[i];
int key = kbItem->qtKey[i];
if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) {
- ret << int(key + (keyMods & ~neededMods));
+ // Patch: Backport a fix for layout-independent keyboard shortcuts.
+ ret << int(key + neededMods);
}
}
return ret;
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 83c960d931..03ae9696af 100755
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -102,7 +102,10 @@ QT_USE_NAMESPACE
QCocoaSystemTrayIcon *systray;
NSStatusItem *item;
QCocoaMenu *menu;
- bool menuVisible;
+
+ // Patch: Nice macOS tray icon support.
+ bool menuVisible, iconSelected;
+
QIcon icon;
QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
}
@@ -124,6 +127,10 @@ QT_USE_NAMESPACE
QT_MANGLE_NAMESPACE(QNSStatusItem) *parent;
}
-(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent;
+
+// Patch: Nice macOS tray icon support.
+-(void)updateIconSelection;
+
-(void)menuTrackingDone:(NSNotification*)notification;
-(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton;
@end
@@ -187,6 +194,19 @@ void QCocoaSystemTrayIcon::cleanup()
m_sys = 0;
}
+// Patch: Nice macOS tray icon support.
+namespace {
+
+qreal getDevicePixelRatio() {
+ qreal result = 1.0;
+ foreach (QScreen *screen, QGuiApplication::screens()) {
+ result = qMax(result, screen->devicePixelRatio());
+ }
+ return result;
+}
+
+} // namespace
+
void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
{
if (!m_sys)
@@ -194,13 +214,18 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
m_sys->item->icon = icon;
- const bool menuVisible = m_sys->item->menu && m_sys->item->menuVisible;
+ // Patch: Nice macOS tray icon support.
+ //const bool menuVisible = m_sys->item->menu && m_sys->item->menuVisible;
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
+ const int padding = 0;
+ const int menuHeight = [[NSStatusBar systemStatusBar] thickness];
+ const int maxImageHeight = menuHeight - padding;
+
+ const short scale = maxImageHeight * getDevicePixelRatio();
QPixmap pm = m_sys->item->icon.pixmap(QSize(scale, scale),
- menuVisible ? QIcon::Selected : QIcon::Normal);
+ // Patch: Nice macOS tray icon support.
+ m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal);
if (pm.isNull()) {
pm = QPixmap(scale, scale);
pm.fill(Qt::transparent);
@@ -322,15 +347,16 @@ QT_END_NAMESPACE
return self;
}
--(void)menuTrackingDone:(NSNotification*)notification
+// Patch: Nice macOS tray icon support.
+-(void)updateIconSelection
{
- Q_UNUSED(notification);
- down = NO;
+ const int padding = 0;
+ const int menuHeight = [[NSStatusBar systemStatusBar] thickness];
+ const int maxImageHeight = menuHeight - padding;
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
-
- QPixmap pm = parent->icon.pixmap(QSize(scale, scale), QIcon::Normal);
+ const short scale = maxImageHeight * getDevicePixelRatio();
+ QPixmap pm = parent->icon.pixmap(QSize(scale, scale),
+ parent->iconSelected ? QIcon::Selected : QIcon::Normal);
if (pm.isNull()) {
pm = QPixmap(scale, scale);
pm.fill(Qt::transparent);
@@ -338,9 +364,19 @@ QT_END_NAMESPACE
NSImage *nsaltimage = static_cast<NSImage *>(qt_mac_create_nsimage(pm));
[self setImage: nsaltimage];
[nsaltimage release];
+}
+
+-(void)menuTrackingDone:(NSNotification*)notification
+{
+ Q_UNUSED(notification);
+ down = NO;
parent->menuVisible = false;
+ // Patch: Nice macOS tray icon support.
+ parent->iconSelected = false;
+ [self updateIconSelection];
+
[self setNeedsDisplay:YES];
}
@@ -350,18 +386,9 @@ QT_END_NAMESPACE
int clickCount = [mouseEvent clickCount];
[self setNeedsDisplay:YES];
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
-
- QPixmap pm = parent->icon.pixmap(QSize(scale, scale),
- parent->menuVisible ? QIcon::Selected : QIcon::Normal);
- if (pm.isNull()) {
- pm = QPixmap(scale, scale);
- pm.fill(Qt::transparent);
- }
- NSImage *nsaltimage = static_cast<NSImage *>(qt_mac_create_nsimage(pm));
- [self setImage: nsaltimage];
- [nsaltimage release];
+ // Patch: Nice macOS tray icon support.
+ parent->iconSelected = (clickCount != 2) && parent->menu;
+ [self updateIconSelection];
if (clickCount == 2) {
[self menuTrackingDone:nil];
@@ -380,6 +407,10 @@ QT_END_NAMESPACE
{
Q_UNUSED(mouseEvent);
[self menuTrackingDone:nil];
+
+ // Patch: Nice macOS tray icon support.
+ parent->iconSelected = false;
+ [self updateIconSelection];
}
- (void)rightMouseDown:(NSEvent *)mouseEvent
@@ -391,6 +422,10 @@ QT_END_NAMESPACE
{
Q_UNUSED(mouseEvent);
[self menuTrackingDone:nil];
+
+ // Patch: Nice macOS tray icon support.
+ parent->iconSelected = false;
+ [self updateIconSelection];
}
- (void)otherMouseDown:(NSEvent *)mouseEvent
@@ -405,7 +440,8 @@ QT_END_NAMESPACE
}
-(void)drawRect:(NSRect)rect {
- [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down];
+ // Patch: Nice macOS tray icon support.
+ [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO];
[super drawRect:rect];
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 4d0458a4aa..3357a5ef81 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -167,7 +167,8 @@ static bool isMouseEvent(NSEvent *ev)
if (!self.window.delegate)
return; // Already detached, pending NSAppKitDefined event
- if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
+ // Patch: Fix events loss if the window was minimized or hidden.
+ if (pw && pw->frameStrutEventsEnabled() && pw->m_synchedWindowState != Qt::WindowMinimized && pw->m_isExposed && isMouseEvent(theEvent)) {
NSPoint loc = [theEvent locationInWindow];
NSRect windowFrame = [self.window legacyConvertRectFromScreen:[self.window frame]];
NSRect contentFrame = [[self.window contentView] frame];
@@ -795,6 +796,16 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
{
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
NSInteger styleMask = NSBorderlessWindowMask;
+
+ // Patch: allow creating panels floating on all spaces in macOS.
+ // If you call "setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary" before
+ // setting the "NSNonactivatingPanelMask" bit in the style mask it won't work after that.
+ // So we need a way to set that bit before Qt sets collection behavior the way it does.
+ QVariant nonactivatingPanelMask = window()->property("_td_macNonactivatingPanelMask");
+ if (nonactivatingPanelMask.isValid() && nonactivatingPanelMask.toBool()) {
+ styleMask |= NSNonactivatingPanelMask;
+ }
+
if (flags & Qt::FramelessWindowHint)
return styleMask;
if ((type & Qt::Popup) == Qt::Popup) {
@@ -914,6 +925,19 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
[m_nsWindow setRepresentedFilename: fi.exists() ? QCFString::toNSString(filePath) : @""];
}
+// Patch: Nice macOS window icon.
+namespace {
+
+qreal getDevicePixelRatio() {
+ qreal result = 1.0;
+ foreach (QScreen *screen, QGuiApplication::screens()) {
+ result = qMax(result, screen->devicePixelRatio());
+ }
+ return result;
+}
+
+} // namespace
+
void QCocoaWindow::setWindowIcon(const QIcon &icon)
{
QCocoaAutoReleasePool pool;
@@ -929,7 +953,10 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
if (icon.isNull()) {
[iconButton setImage:nil];
} else {
- QPixmap pixmap = icon.pixmap(QSize(22, 22));
+ // Patch: Nice macOS window icon.
+ CGFloat hgt = 16. * getDevicePixelRatio();
+ QPixmap pixmap = icon.pixmap(QSize(hgt, hgt));
+
NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
[iconButton setImage:image];
[image release];
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index a18ee7ff71..1f91feb0ae 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -393,7 +393,9 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
[self notifyWindowStateChanged:newState];
// NSWindowDidOrderOnScreenAndFinishAnimatingNotification is private API, and not
// emitted in 10.6, so we bring back the old behavior for that case alone.
- if (newState == Qt::WindowNoState && QSysInfo::QSysInfo::MacintoshVersion == QSysInfo::MV_10_6)
+
+ // Patch: Fix macOS window show after window was hidden.
+ if (newState == Qt::WindowNoState/* && QSysInfo::QSysInfo::MacintoshVersion == QSysInfo::MV_10_6*/)
m_platformWindow->exposeWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
m_platformWindow->obscureWindow();
@@ -1300,7 +1302,9 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
// On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin.
- if (phase == NSEventPhaseMayBegin)
+
+ // Patch: Actual begin should be treated as begin as well.
+ if (phase == NSEventPhaseMayBegin || phase == NSEventPhaseBegan)
ph = Qt::ScrollBegin;
} else
#endif
@@ -1366,14 +1370,22 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
quint32 nativeVirtualKey = [nsevent keyCode];
QChar ch = QChar::ReplacementCharacter;
- int keyCode = Qt::Key_unknown;
- if ([characters length] != 0) {
- if (((modifiers & Qt::MetaModifier) || (modifiers & Qt::AltModifier)) && ([charactersIgnoringModifiers length] != 0))
- ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
- else
- ch = QChar([characters characterAtIndex:0]);
- keyCode = [self convertKeyCode:ch];
- }
+
+ // Patch: Backport a fix for layout-independent shortcuts.
+ if ([characters length] != 0) // https://bugreports.qt.io/browse/QTBUG-42584
+ ch = QChar([characters characterAtIndex:0]);
+ else if ([charactersIgnoringModifiers length] != 0 && ((modifiers & Qt::MetaModifier) || (modifiers & Qt::AltModifier)))
+ ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
+
+ int keyCode = [self convertKeyCode:ch];
+ //int keyCode = Qt::Key_unknown;
+ //if ([characters length] != 0) {
+ // if (((modifiers & Qt::MetaModifier) || (modifiers & Qt::AltModifier)) && ([charactersIgnoringModifiers length] != 0))
+ // ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
+ // else
+ // ch = QChar([characters characterAtIndex:0]);
+ // keyCode = [self convertKeyCode:ch];
+ //}
// we will send a key event unless the input method sets m_sendKeyEvent to false
m_sendKeyEvent = true;
@@ -1437,6 +1449,11 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
&& qtKey == Qt::Key_Period) {
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
return YES;
+
+ // Patch: Allow us to handle Ctrl+Tab and Ctrl+Backtab in the app.
+ } else if ([nsevent modifierFlags] & NSControlKeyMask && (qtKey == Qt::Key_Tab || qtKey == Qt::Key_Backtab)) {
+ [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
+ return YES;
}
}
return [super performKeyEquivalent:nsevent];
diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp
index c68076477f..e2a7aafa58 100644
--- a/src/tools/qlalr/lalr.cpp
+++ b/src/tools/qlalr/lalr.cpp
@@ -246,11 +246,13 @@ void Grammar::buildExtendedGrammar ()
non_terminals.insert (accept_symbol);
}
-struct _Nullable: public std::unary_function<Name, bool>
+// Patch: Fix building with the new SDK.
+struct __Nullable: public std::unary_function<Name, bool>
{
Automaton *_M_automaton;
- _Nullable (Automaton *aut):
+ // Patch: Fix building with the new SDK.
+ __Nullable (Automaton *aut):
_M_automaton (aut) {}
bool operator () (Name name) const
@@ -308,7 +310,8 @@ void Automaton::buildNullables ()
for (RulePointer rule = _M_grammar->rules.begin (); rule != _M_grammar->rules.end (); ++rule)
{
- NameList::iterator nn = std::find_if (rule->rhs.begin (), rule->rhs.end (), std::not1 (_Nullable (this)));
+ // Patch: Fix building with the new SDK.
+ NameList::iterator nn = std::find_if (rule->rhs.begin (), rule->rhs.end (), std::not1 (__Nullable (this)));
if (nn == rule->rhs.end ())
changed |= nullables.insert (rule->lhs).second;
@@ -643,7 +646,8 @@ void Automaton::buildIncludesDigraph ()
if (! _M_grammar->isNonTerminal (*A))
continue;
- NameList::iterator first_not_nullable = std::find_if (dot, rule->rhs.end (), std::not1 (_Nullable (this)));
+ // Patch: Fix building with the new SDK.
+ NameList::iterator first_not_nullable = std::find_if (dot, rule->rhs.end (), std::not1 (__Nullable (this)));
if (first_not_nullable != rule->rhs.end ())
continue;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 7396808442..7178aecf80 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -4722,6 +4722,17 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
return; // Fully transparent.
Q_D(QWidget);
+
+ // Patch: save and restore dirtyOpaqueChildren field.
+ //
+ // Just like in QWidget::grab() this field should be restored
+ // after the d->render() call, because it will be set to 1 and
+ // opaqueChildren field will be filled with empty region in
+ // case the widget is hidden (because all the opaque children
+ // will be skipped in isVisible() check).
+ //
+ const bool oldDirtyOpaqueChildren = d->dirtyOpaqueChildren;
+
const bool inRenderWithPainter = d->extra && d->extra->inRenderWithPainter;
const QRegion toBePainted = !inRenderWithPainter ? d->prepareToRender(sourceRegion, renderFlags)
: sourceRegion;
@@ -4743,6 +4754,10 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) {
d->render_helper(painter, targetOffset, toBePainted, renderFlags);
d->extra->inRenderWithPainter = inRenderWithPainter;
+
+ // Patch: save and restore dirtyOpaqueChildren field.
+ d->dirtyOpaqueChildren = oldDirtyOpaqueChildren;
+
return;
}
@@ -4774,6 +4789,9 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
d->setSharedPainter(oldPainter);
d->extra->inRenderWithPainter = inRenderWithPainter;
+
+ // Patch: save and restore dirtyOpaqueChildren field.
+ d->dirtyOpaqueChildren = oldDirtyOpaqueChildren;
}
static void sendResizeEvents(QWidget *target)
@@ -7983,7 +8001,8 @@ bool QWidget::event(QEvent *event)
case QEvent::KeyPress: {
QKeyEvent *k = (QKeyEvent *)event;
bool res = false;
- if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
+ // Patch: Allow us to handle Ctrl+Tab and Ctrl+Backtab in the app.
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))) { //### Add MetaModifier?
if (k->key() == Qt::Key_Backtab
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
res = focusNextPrevChild(false);
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 0845a5eb02..5735cb6b39 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -3667,9 +3667,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
NSBezierPath *pushButtonFocusRingPath;
if (bdi.kind == kThemeBevelButton)
- pushButtonFocusRingPath = [NSBezierPath bezierPathWithRect:focusRect];
+ // Patch: Fix building with the new SDK.
+ pushButtonFocusRingPath = [NSBezierPath bezierPathWithRect:NSRectFromCGRect(focusRect)];
else
- pushButtonFocusRingPath = [NSBezierPath bezierPathWithRoundedRect:focusRect xRadius:4 yRadius:4];
+ // Patch: Fix building with the new SDK.
+ pushButtonFocusRingPath = [NSBezierPath bezierPathWithRoundedRect:NSRectFromCGRect(focusRect) xRadius:4 yRadius:4];
qt_drawFocusRingOnPath(cg, pushButtonFocusRingPath);
}
diff --git a/src/widgets/util/qsystemtrayicon_qpa.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp
index f98aeaf678..00c0734129 100644
--- a/src/widgets/util/qsystemtrayicon_qpa.cpp
+++ b/src/widgets/util/qsystemtrayicon_qpa.cpp
@@ -99,13 +99,18 @@ void QSystemTrayIconPrivate::updateIcon_sys()
void QSystemTrayIconPrivate::updateMenu_sys()
{
- if (qpa_sys && menu) {
- if (!menu->platformMenu()) {
- QPlatformMenu *platformMenu = qpa_sys->createMenu();
- if (platformMenu)
- menu->setPlatformMenu(platformMenu);
+ // Patch: Nice macOS tray icon support.
+ if (qpa_sys) {
+ if (menu) {
+ if (!menu->platformMenu()) {
+ QPlatformMenu *platformMenu = qpa_sys->createMenu();
+ if (platformMenu)
+ menu->setPlatformMenu(platformMenu);
+ }
+ qpa_sys->updateMenu(menu->platformMenu());
+ } else {
+ qpa_sys->updateMenu(0);
}
- qpa_sys->updateMenu(menu->platformMenu());
}
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 75f30599be..980f2be1e9 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -1867,7 +1867,8 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
if (unknown && !isReadOnly()) {
QString t = event->text();
- if (!t.isEmpty() && t.at(0).isPrint()) {
+ // Patch: Enable ZWJ and ZWNJ characters to be in text input.
+ if (!t.isEmpty() && (t.at(0).isPrint() || t.at(0).unicode() == 0x200C || t.at(0).unicode() == 0x200D)) {
insert(t);
#ifndef QT_NO_COMPLETER
complete(event->key());
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 96438a0bdf..b0b7206405 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1342,7 +1342,8 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
process:
{
QString text = e->text();
- if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) {
+ // Patch: Enable ZWJ and ZWNJ characters to be in text input.
+ if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t') || text.at(0).unicode() == 0x200C || text.at(0).unicode() == 0x200D)) {
if (overwriteMode
// no need to call deleteChar() if we have a selection, insertText
// does it already