845 lines
36 KiB
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
|