tdesktop/Telegram/Patches/qtbase_5_6_2.diff

1709 lines
72 KiB
Diff
Raw Normal View History

diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf
index eec9e1f688..7ae53c7a1e 100644
--- a/mkspecs/common/msvc-desktop.conf
+++ b/mkspecs/common/msvc-desktop.conf
@@ -30,9 +30,10 @@ QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS = -nologo -Zc:wchar_t
QMAKE_CFLAGS_WARN_ON = -W3
QMAKE_CFLAGS_WARN_OFF = -W0
-QMAKE_CFLAGS_RELEASE = -O2 -MD
-QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi
-QMAKE_CFLAGS_DEBUG = -Zi -MDd
+# Patch: Make this build use static runtime library.
+QMAKE_CFLAGS_RELEASE = -O2 -MT
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
+QMAKE_CFLAGS_DEBUG = -Zi -MTd
QMAKE_CFLAGS_YACC =
QMAKE_CFLAGS_LTCG = -GL
QMAKE_CFLAGS_SSE2 = -arch:SSE2
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 391fbcc519..d07802bb7a 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -427,11 +427,12 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len)
// Writing on Windows fails with ERROR_NO_SYSTEM_RESOURCES when
// the chunks are too large, so we limit the block size to 32MB.
- const DWORD blockSize = DWORD(qMin(bytesToWrite, qint64(32 * 1024 * 1024)));
qint64 totalWritten = 0;
do {
+ // Patch: backport critical bugfix from '683c9bc4a8' commit.
+ const DWORD currentBlockSize = DWORD(qMin(bytesToWrite, qint64(32 * 1024 * 1024)));
DWORD bytesWritten;
- if (!WriteFile(fileHandle, data + totalWritten, blockSize, &bytesWritten, NULL)) {
+ if (!WriteFile(fileHandle, data + totalWritten, currentBlockSize, &bytesWritten, NULL)) {
if (totalWritten == 0) {
// Note: Only return error if the first WriteFile failed.
q->setError(QFile::WriteError, qt_error_string());
diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp
index 14e4fd10aa..0619a176a7 100644
--- a/src/corelib/tools/qunicodetables.cpp
+++ b/src/corelib/tools/qunicodetables.cpp
@@ -6227,7 +6227,8 @@ static const Properties uc_properties[] = {
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 11 },
{ 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 8, 8, 12, 11 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 17, 2 },
+ // Patch: Some bad characters appeared in ui in case 2 was here instead of 11.
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 17, 11 },
{ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
{ 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
{ 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 2d00b9dce9..eeba86e936 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -51,6 +51,9 @@ static const char screenFactorsEnvVar[] = "QT_SCREEN_SCALE_FACTORS";
static inline qreal initialGlobalScaleFactor()
{
+ // Patch: Disable environment variable dpi scaling changing.
+ // It is not supported by Telegram Desktop :(
+ return 1.;
qreal result = 1;
if (qEnvironmentVariableIsSet(scaleFactorEnvVar)) {
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index 5b2f4ece77..790db46d25 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -386,6 +386,10 @@ public:
virtual QUrl directory() const = 0;
virtual void selectFile(const QUrl &filename) = 0;
virtual QList<QUrl> selectedFiles() const = 0;
+
+ // Patch: Adding select-by-url for Windows file dialog.
+ virtual QByteArray selectedRemoteContent() const { return QByteArray(); }
+
virtual void setFilter() = 0;
virtual void selectNameFilter(const QString &filter) = 0;
virtual QString selectedNameFilter() const = 0;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index bcd29b6fe1..bcb0672f69 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -2525,7 +2525,8 @@ void QWindowPrivate::setCursor(const QCursor *newCursor)
void QWindowPrivate::applyCursor()
{
Q_Q(QWindow);
- if (platformWindow) {
+ // Patch: Fixing possible crash (crashdumps point on this code line).
+ if (platformWindow && q->screen() && q->screen()->handle()) {
if (QPlatformCursor *platformCursor = q->screen()->handle()->cursor()) {
QCursor *c = QGuiApplication::overrideCursor();
if (!c && hasCursor)
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index 8e0e76f787..a61bd62834 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -45,6 +45,34 @@ QT_BEGIN_NAMESPACE
//#define QDEBUG_BEZIER
+// Patch: Workaround VS2019 compiler bug, see QTBUG-75280.
+#ifdef Q_OS_WIN
+Q_NEVER_INLINE void QBezier::split(QBezier *firstHalf, QBezier *secondHalf) const
+{
+ Q_ASSERT(firstHalf);
+ Q_ASSERT(secondHalf);
+
+ qreal c = (x2 + x3)*.5;
+ firstHalf->x2 = (x1 + x2)*.5;
+ secondHalf->x3 = (x3 + x4)*.5;
+ firstHalf->x1 = x1;
+ secondHalf->x4 = x4;
+ firstHalf->x3 = (firstHalf->x2 + c)*.5;
+ secondHalf->x2 = (secondHalf->x3 + c)*.5;
+ firstHalf->x4 = secondHalf->x1 = (firstHalf->x3 + secondHalf->x2)*.5;
+
+ c = (y2 + y3)/2;
+ firstHalf->y2 = (y1 + y2)*.5;
+ secondHalf->y3 = (y3 + y4)*.5;
+ firstHalf->y1 = y1;
+ secondHalf->y4 = y4;
+ firstHalf->y3 = (firstHalf->y2 + c)*.5;
+ secondHalf->y2 = (secondHalf->y3 + c)*.5;
+ firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2)*.5;
+}
+// Patch: Workaround VS2019 compiler bug, see QTBUG-75280.
+#endif // Q_OS_WIN
+
/*!
\internal
*/
diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h
index dd1cd94acf..aedc8b6a4b 100644
--- a/src/gui/painting/qbezier_p.h
+++ b/src/gui/painting/qbezier_p.h
@@ -215,6 +215,8 @@ inline QPointF QBezier::secondDerivedAt(qreal t) const
a * y1 + b * y2 + c * y3 + d * y4);
}
+// Patch: Workaround VS2019 compiler bug, see QTBUG-75280.
+#ifndef Q_OS_WIN
inline void QBezier::split(QBezier *firstHalf, QBezier *secondHalf) const
{
Q_ASSERT(firstHalf);
@@ -238,6 +240,8 @@ inline void QBezier::split(QBezier *firstHalf, QBezier *secondHalf) const
secondHalf->y2 = (secondHalf->y3 + c)*.5;
firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2)*.5;
}
+// Patch: Workaround VS2019 compiler bug, see QTBUG-75280.
+#endif // Q_OS_WIN
inline void QBezier::parameterSplitLeft(qreal t, QBezier *left)
{
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index 918c98997b..4158259743 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -80,8 +80,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/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 7e507bba2d..936e7a92cb 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -283,7 +283,8 @@ private:
struct QScriptItem;
/// Internal QTextItem
-class QTextItemInt : public QTextItem
+// Patch: Enable access to QTextItemInt in .dll for WinRT build.
+class Q_GUI_EXPORT QTextItemInt : public QTextItem
{
public:
inline QTextItemInt()
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index aca475a581..5fa0be2c45 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -694,6 +694,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))
@@ -702,8 +705,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
while (oldPos < len && !attributes[oldPos].whiteSpace && !d->atWordSeparator(oldPos))
oldPos++;
}
- while (oldPos < len && attributes[oldPos].whiteSpace)
- oldPos++;
+ // Patch: Skip to the end of the current word, not to the start of the next one.
+ //while (oldPos < len && attributes[oldPos].whiteSpace)
+ // oldPos++;
}
return oldPos;
@@ -1645,6 +1649,9 @@ namespace {
int currentPosition;
glyph_t previousGlyph;
+ // Patch: Fix a crash in right bearing calculation.
+ QFontEngine *previousGlyphFontEngine;
+
QFixed minw;
QFixed softHyphenWidth;
QFixed rightBearing;
@@ -1677,13 +1684,19 @@ namespace {
if (currentPosition > 0 &&
logClusters[currentPosition - 1] < glyphs.numGlyphs) {
previousGlyph = currentGlyph(); // needed to calculate right bearing later
+
+ // Patch: Fix a crash in right bearing calculation.
+ previousGlyphFontEngine = fontEngine;
}
}
- inline void calculateRightBearing(glyph_t glyph)
+ // Patch: Fix a crash in right bearing calculation.
+ inline void calculateRightBearing(QFontEngine *engine, glyph_t glyph)
{
qreal rb;
- fontEngine->getGlyphBearings(glyph, 0, &rb);
+
+ // Patch: Fix a crash in right bearing calculation.
+ engine->getGlyphBearings(glyph, 0, &rb);
// We only care about negative right bearings, so we limit the range
// of the bearing here so that we can assume it's negative in the rest
@@ -1696,13 +1709,16 @@ namespace {
{
if (currentPosition <= 0)
return;
- calculateRightBearing(currentGlyph());
+
+ // Patch: Fix a crash in right bearing calculation.
+ calculateRightBearing(fontEngine, currentGlyph());
}
inline void calculateRightBearingForPreviousGlyph()
{
if (previousGlyph > 0)
- calculateRightBearing(previousGlyph);
+ // Patch: Fix a crash in right bearing calculation.
+ calculateRightBearing(previousGlyphFontEngine, previousGlyph);
}
static const QFixed RightBearingNotCalculated;
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index f74d4d4229..8ad672c9fe 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -196,6 +196,9 @@ private:
QRectF *brect, int tabstops, int* tabarray, int tabarraylen,
QPainter *painter);
QTextEngine *d;
+
+ // Patch: Allow access to private constructor.
+ friend class TextBlock;
};
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index c4cb8e65c0..45793e364f 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -110,6 +110,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/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 94235a48dd..9abd2cc0a1 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -2045,6 +2045,9 @@ void QNetworkReplyHttpImplPrivate::finished()
{
Q_Q(QNetworkReplyHttpImpl);
+ // Patch: Fix crash in Linux (by crashreports).
+ QPointer<QNetworkReplyHttpImpl> guard = q;
+
if (state == Finished || state == Aborted || state == WaitingForSession)
return;
@@ -2075,6 +2078,9 @@ void QNetworkReplyHttpImplPrivate::finished()
#endif
}
+ // Patch: Fix crash in Linux (by crashreports).
+ if (!guard) return;
+
// if we don't know the total size of or we received everything save the cache
if (totalSize.isNull() || totalSize == -1 || bytesDownloaded == totalSize)
completeCacheSave();
@@ -2084,6 +2090,9 @@ void QNetworkReplyHttpImplPrivate::finished()
if (isHttpRedirectResponse() && errorCode == QNetworkReply::NoError)
return;
+ // Patch: Fix crash in Linux (by crashreports).
+ if (!guard) return;
+
state = Finished;
q->setFinished(true);
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 41834b21ae..8cdf4ab145 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -675,6 +675,13 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
errorDetected = true;
break;
}
+ // Patch: Handle network unreachable the same as host unreachable.
+ if (value == WSAENETUNREACH) {
+ setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
+ errorDetected = true;
+ break;
+ }
if (value == WSAEADDRNOTAVAIL) {
setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
socketState = QAbstractSocket::UnconnectedState;
diff --git a/src/platformsupport/cglconvenience/cglconvenience.mm b/src/platformsupport/cglconvenience/cglconvenience.mm
index fb609ae485..ef1c638d91 100644
--- a/src/platformsupport/cglconvenience/cglconvenience.mm
+++ b/src/platformsupport/cglconvenience/cglconvenience.mm
@@ -128,7 +128,12 @@ void *qcgl_createNSOpenGLPixelFormat(const QSurfaceFormat &format)
if (format.stereo())
attrs << NSOpenGLPFAStereo;
- attrs << NSOpenGLPFAAllowOfflineRenderers;
+ // Patch: Fix macOS regression. On 10.14.4, it crashes on GPU switches.
+ // See https://bugreports.qt.io/browse/QTCREATORBUG-22215
+ static const QAppleOperatingSystemVersion version = qt_apple_os_version();
2019-06-02 09:35:02 +00:00
+ if (!(version.major == 10 && version.minor == 14 && version.patch == 4)) {
+ attrs << NSOpenGLPFAAllowOfflineRenderers;
+ }
QByteArray useLayer = qgetenv("QT_MAC_WANTS_LAYER");
if (!useLayer.isEmpty() && useLayer.toInt() > 0) {
Snap packaging support (#4505) * qtbuilder: inherit from make plugin instead of autotools * qtbuilder: update to properly support snapcraft 2.23 We don't use the default 'source' property as it will recursively download all the submodules and we don't want that. Implement newer get_pull_properties. * gyp-cmake: only strip in Release mode and if we've a binary * telegram-snap: add first basic snapcraft.yaml to build tdesktop from src We need to build upstream versions of libva, ffmpeg (with opus support), openal, portaudio with custom flags and patched versions of gyp, and Qt. This requires some custom plugins for patching sources, mix repos and new build plugins for qt and gyp+cmake. * plugins: properly support snapcraft 2.23 Implementing get_pull_properties class methods * patches: add qt patch for saving tray icon in .cache TMPDIR overriding isn't needed anymore * snapcraft: add xdg-open support to open URIs * snapcraft: move external libraries to desktop-integration part * snapcraft: set QTCOMPOSE pointing to proper x11-data * desktop-integration: add libpulse0 to enable voice/video recording / playing * qtbuilder: add support for local patches that overrides remote ones * qtbuilder: make qt-version optional This allows to build upstream git version * gyp-cmake: inherit from CMakePlugin reusing artifacts + organize * patched-python: add support for patching using local files * snapcraft.yaml: use distro's portaudio instead of building ours * telegram: disable desktop file generation and custuom scheme registration * snapcraft.yaml: update version to 0.10.20 * .travis.yaml: add support for building using travis * qtbuilder: add g++ as build packages * snapcraft: use distro opus version * snapcraft: lzma for qt and ffmpeg * snapcraft: add libdbusmenu for qt * openal: add oss4-dev as build dependency * travis: test some hacks to speed things up * Move plugins to new dir * QtBuilder: add qt-extra-plugins support To include plugins that are out of the main qt repo * QtBuilder: generate branch based on qtversion * GypCMake: allow to define custom environment variables * snapcraft: set name to 'telegram-desktop' * snapcraft: add 'network-status' interface to Telegram app To automatically reconnect * snapcraft: use prime instead of snap for flitering files * snacpraft: update dependencies and versions to build against git * snapcraft: build with GCC-7 hackish solution * QtBuilder: add environment support * QtBuilder: add qt-extra-plugins to get_pull_properties * snapcraft: set name of the app to telegram-desktop too * snapcraft: build opus from git (v1.2.1) So it does upstream, let's follow them * telegram: apply patch to get proper home path from $HOME * snapcraft: add version-script to generate proper version from upstream * telegram: simplify the start command * snapcraft: get rid of snapd-xdg-open * snapcraft: use gtk3 and unity integration * qt5: build using gcc7 too * telegram-desktop: update desktop file * telegram: add support unity launcher when snapped We should actually fix this inside libunity * gcc7: remove toolchain source.list after install * desktop-integration: add pulse-audio as dependency again * telegram-desktop: define XCURSOR_PATH to get system cursors * gui: move files to snap folder * libtgvoip: don't enable SSE2 in unsupported archs * snapcraft: add -alpha sufix on versions and do not include git for tags * telegram: add patch for building in ARM chips * desktop-integration: include libunity * telegram-desktop: no need to define XCURSOR_PATH anymore, desktop helper will do * snapcraft: compile libunity from upstream to get proper launcher integration Drop custom patch, it's just better to do it here. This means we go back to upstream telegramdesktop desktop-id too. * telegram: get desktop file and icon from telegram part source * snapcraft: improve snap description * gcc7: not needed to add devscripts or equivs Unless we try to build gcc7 here, which well... A bit time consuming. * libunity: use upstream branch (my changes just merged) * ci: remove travis integration, it takes to long b.s.io does it already * telegram: don't do unneeded checks in armhf * telegram: more signed/unsigned char fixes for ARM, ignore errors for now * telegram: add getclock definitions for ARM * telegram: arm support, always use signed chars * telegram: don't need to use signed chars in ARM anymmore As we've fixed all the issues * telegram: replace .desktop file icon with snap one, add keywords * snapcraft: use diversity check on alpha value * telegram: detect Ubuntu desktop adding support for badges and indicators * telegram: unset WAYLAND_DISPLAY to get it running properly * Add a README * telegram: just add network-observe plug * snapcraft: add beta detection * snapcraft: only add network-manager plug, users might connect it We should actually have a connection-observe plug. * patches: add patch to use a customizable working dir in debug * snapcraft: define again QT_IM_MODULE and QTCOMPOSE fix compose key Setting compose to proper paths will allow to get composition key working again in snapped QT apps. * desktop-integration: add indicator-gtk3 and chinese fonts * desktop-integration: don't snap fonts, use desktop interface Fonts are now bind-mounted from host by the desktop interface * patches: apply patches using 3way merge if they fail * patches: update telegram-arm-support to apply cleanly * snapcraft: disable wayland using desktop script env * snapcraft: libunity has been SRU'ed, we can go back to archive version * patches: update arm support patch * breakpad: use upstream versions * telegram, patches: remove upstreamed patches * patches: disable Werror It causes failures in some archs, and we don't care much at this level (for now). * patches: remove libtgvoip msse2 patch * Revert "patches: remove libtgvoip msse2 patch" Not yet in the submodule used by telegram desktop This reverts commit 2e6f4cc619ee591fdd250cb3b2af4f0330d1c4ca. * snapcraft: show bash debugging on version script * desktop-gtk3: update mime database and icon-cache during install This saves some startup time * telegram: add gsettings plug * telegram-launch: use user-common as home and migrate if needed * Import snap folder from telegram-snap repo * patches, qtbase: use indicator icon in unity or ubuntu Patch already applied upstream, remove from snap only * .gitignore: add snap related files * telegram-launch: merge downloaded files folder if found * snap: remove patches not needed for upstream * snap, patch, libtgvoip: sync with upstream * telegram-launch: remove default dir after moving download files * snap: remove libtgvoip patches, we can just update the submodule The actual module update should be managed in a different commit though. * snapcraft: explain why gcc7 part is needed * snapcraft: update summary text * qt: no need to build gstreamer, and reorder configflags * plugins: add copyright informations * telegram: add common-id and parse-info with AppData Use the appstream integration that snapcraft now supports. * openal: use v1.18 branch as upstream does now * qtbuilder: support tags in versions better * qtbuilder: use shutil.rmtree to remove files * telegram: set QT_IM_MODULE only if not set * telegram: add removable-media plug * telegram-launch: ignore ibus as input method And add support for getting it from $TELEGRAM_QT_IM_MODULE env var * snapcraft: use git describe to get revision * snapcraft: use override-* stanzas for scriptlets * snap: exit scriptlets on first error * snap: remove summary, inherit from AppData * lib_export: use includes paths as defined per platform
2018-07-21 14:35:37 +00:00
diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp
index 4d6e70720d..9bdb0beb67 100644
Snap packaging support (#4505) * qtbuilder: inherit from make plugin instead of autotools * qtbuilder: update to properly support snapcraft 2.23 We don't use the default 'source' property as it will recursively download all the submodules and we don't want that. Implement newer get_pull_properties. * gyp-cmake: only strip in Release mode and if we've a binary * telegram-snap: add first basic snapcraft.yaml to build tdesktop from src We need to build upstream versions of libva, ffmpeg (with opus support), openal, portaudio with custom flags and patched versions of gyp, and Qt. This requires some custom plugins for patching sources, mix repos and new build plugins for qt and gyp+cmake. * plugins: properly support snapcraft 2.23 Implementing get_pull_properties class methods * patches: add qt patch for saving tray icon in .cache TMPDIR overriding isn't needed anymore * snapcraft: add xdg-open support to open URIs * snapcraft: move external libraries to desktop-integration part * snapcraft: set QTCOMPOSE pointing to proper x11-data * desktop-integration: add libpulse0 to enable voice/video recording / playing * qtbuilder: add support for local patches that overrides remote ones * qtbuilder: make qt-version optional This allows to build upstream git version * gyp-cmake: inherit from CMakePlugin reusing artifacts + organize * patched-python: add support for patching using local files * snapcraft.yaml: use distro's portaudio instead of building ours * telegram: disable desktop file generation and custuom scheme registration * snapcraft.yaml: update version to 0.10.20 * .travis.yaml: add support for building using travis * qtbuilder: add g++ as build packages * snapcraft: use distro opus version * snapcraft: lzma for qt and ffmpeg * snapcraft: add libdbusmenu for qt * openal: add oss4-dev as build dependency * travis: test some hacks to speed things up * Move plugins to new dir * QtBuilder: add qt-extra-plugins support To include plugins that are out of the main qt repo * QtBuilder: generate branch based on qtversion * GypCMake: allow to define custom environment variables * snapcraft: set name to 'telegram-desktop' * snapcraft: add 'network-status' interface to Telegram app To automatically reconnect * snapcraft: use prime instead of snap for flitering files * snacpraft: update dependencies and versions to build against git * snapcraft: build with GCC-7 hackish solution * QtBuilder: add environment support * QtBuilder: add qt-extra-plugins to get_pull_properties * snapcraft: set name of the app to telegram-desktop too * snapcraft: build opus from git (v1.2.1) So it does upstream, let's follow them * telegram: apply patch to get proper home path from $HOME * snapcraft: add version-script to generate proper version from upstream * telegram: simplify the start command * snapcraft: get rid of snapd-xdg-open * snapcraft: use gtk3 and unity integration * qt5: build using gcc7 too * telegram-desktop: update desktop file * telegram: add support unity launcher when snapped We should actually fix this inside libunity * gcc7: remove toolchain source.list after install * desktop-integration: add pulse-audio as dependency again * telegram-desktop: define XCURSOR_PATH to get system cursors * gui: move files to snap folder * libtgvoip: don't enable SSE2 in unsupported archs * snapcraft: add -alpha sufix on versions and do not include git for tags * telegram: add patch for building in ARM chips * desktop-integration: include libunity * telegram-desktop: no need to define XCURSOR_PATH anymore, desktop helper will do * snapcraft: compile libunity from upstream to get proper launcher integration Drop custom patch, it's just better to do it here. This means we go back to upstream telegramdesktop desktop-id too. * telegram: get desktop file and icon from telegram part source * snapcraft: improve snap description * gcc7: not needed to add devscripts or equivs Unless we try to build gcc7 here, which well... A bit time consuming. * libunity: use upstream branch (my changes just merged) * ci: remove travis integration, it takes to long b.s.io does it already * telegram: don't do unneeded checks in armhf * telegram: more signed/unsigned char fixes for ARM, ignore errors for now * telegram: add getclock definitions for ARM * telegram: arm support, always use signed chars * telegram: don't need to use signed chars in ARM anymmore As we've fixed all the issues * telegram: replace .desktop file icon with snap one, add keywords * snapcraft: use diversity check on alpha value * telegram: detect Ubuntu desktop adding support for badges and indicators * telegram: unset WAYLAND_DISPLAY to get it running properly * Add a README * telegram: just add network-observe plug * snapcraft: add beta detection * snapcraft: only add network-manager plug, users might connect it We should actually have a connection-observe plug. * patches: add patch to use a customizable working dir in debug * snapcraft: define again QT_IM_MODULE and QTCOMPOSE fix compose key Setting compose to proper paths will allow to get composition key working again in snapped QT apps. * desktop-integration: add indicator-gtk3 and chinese fonts * desktop-integration: don't snap fonts, use desktop interface Fonts are now bind-mounted from host by the desktop interface * patches: apply patches using 3way merge if they fail * patches: update telegram-arm-support to apply cleanly * snapcraft: disable wayland using desktop script env * snapcraft: libunity has been SRU'ed, we can go back to archive version * patches: update arm support patch * breakpad: use upstream versions * telegram, patches: remove upstreamed patches * patches: disable Werror It causes failures in some archs, and we don't care much at this level (for now). * patches: remove libtgvoip msse2 patch * Revert "patches: remove libtgvoip msse2 patch" Not yet in the submodule used by telegram desktop This reverts commit 2e6f4cc619ee591fdd250cb3b2af4f0330d1c4ca. * snapcraft: show bash debugging on version script * desktop-gtk3: update mime database and icon-cache during install This saves some startup time * telegram: add gsettings plug * telegram-launch: use user-common as home and migrate if needed * Import snap folder from telegram-snap repo * patches, qtbase: use indicator icon in unity or ubuntu Patch already applied upstream, remove from snap only * .gitignore: add snap related files * telegram-launch: merge downloaded files folder if found * snap: remove patches not needed for upstream * snap, patch, libtgvoip: sync with upstream * telegram-launch: remove default dir after moving download files * snap: remove libtgvoip patches, we can just update the submodule The actual module update should be managed in a different commit though. * snapcraft: explain why gcc7 part is needed * snapcraft: update summary text * qt: no need to build gstreamer, and reorder configflags * plugins: add copyright informations * telegram: add common-id and parse-info with AppData Use the appstream integration that snapcraft now supports. * openal: use v1.18 branch as upstream does now * qtbuilder: support tags in versions better * qtbuilder: use shutil.rmtree to remove files * telegram: set QT_IM_MODULE only if not set * telegram: add removable-media plug * telegram-launch: ignore ibus as input method And add support for getting it from $TELEGRAM_QT_IM_MODULE env var * snapcraft: use git describe to get revision * snapcraft: use override-* stanzas for scriptlets * snap: exit scriptlets on first error * snap: remove summary, inherit from AppData * lib_export: use includes paths as defined per platform
2018-07-21 14:35:37 +00:00
--- a/src/platformsupport/dbustray/qdbustrayicon.cpp
+++ b/src/platformsupport/dbustray/qdbustrayicon.cpp
@@ -58,9 +58,18 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray")
+static QString cachePath()
+{
+ QString xdgCache = QString::fromUtf8(getenv("XDG_CACHE_HOME"));
+ if (xdgCache.isEmpty()) {
+ xdgCache = QDir::cleanPath(QDir::homePath() + QStringLiteral("/.cache"));
+ }
+ return xdgCache;
+}
+
static const QString KDEItemFormat = QStringLiteral("org.kde.StatusNotifierItem-%1-%2");
static const QString KDEWatcherService = QStringLiteral("org.kde.StatusNotifierWatcher");
-static const QString TempFileTemplate = QDir::tempPath() + QStringLiteral("/qt-trayicon-XXXXXX.png");
+static const QString TempFileTemplate = cachePath() + QStringLiteral("/qt-trayicon-XXXXXX.png");
static const QString XdgNotificationService = QStringLiteral("org.freedesktop.Notifications");
static const QString XdgNotificationPath = QStringLiteral("/org/freedesktop/Notifications");
static const QString DefaultAction = QStringLiteral("default");
@@ -151,6 +160,12 @@ QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon)
uint pid = session.interface()->servicePid(KDEWatcherService).value();
QString processName = QLockFilePrivate::processNameByPid(pid);
necessary = processName.endsWith(QStringLiteral("indicator-application-service"));
+ if (!necessary) {
+ QString xdgDesktop = QString::fromUtf8(getenv("XDG_CURRENT_DESKTOP"));
+ QStringList desktops = xdgDesktop.toLower().split(QLatin1Char(':'));
+ necessary = desktops.contains(QStringLiteral("unity")) ||
+ desktops.contains(QStringLiteral("ubuntu"));
+ }
necessity_checked = true;
}
if (!necessary)
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 728b166b71..1dc64593e1 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -172,6 +172,79 @@ void QBasicFontDatabase::releaseHandle(void *handle)
extern FT_Library qt_getFreetype();
+// Patch: Enable Open Sans Semibold font family reading.
+// Copied from freetype with some modifications.
+
+#ifndef FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY
+#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG('i', 'g', 'p', 'f')
+#endif
+
+#ifndef FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY
+#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG('i', 'g', 'p', 's')
+#endif
+
+/* there's a Mac-specific extended implementation of FT_New_Face() */
+/* in src/base/ftmac.c */
+
+#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )
+
+/* documentation is in freetype.h */
+
+FT_Error __ft_New_Face(FT_Library library, const char* pathname, FT_Long face_index, FT_Face *aface) {
+ FT_Open_Args args;
+
+ /* test for valid `library' and `aface' delayed to FT_Open_Face() */
+ if (!pathname)
+ return FT_Err_Invalid_Argument;
+
+ FT_Parameter params[2];
+ params[0].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY;
+ params[0].data = 0;
+ params[1].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY;
+ params[1].data = 0;
+ args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;
+ args.pathname = (char*)pathname;
+ args.stream = NULL;
+ args.num_params = 2;
+ args.params = params;
+
+ return FT_Open_Face(library, &args, face_index, aface);
+}
+
+#else
+
+FT_Error __ft_New_Face(FT_Library library, const char* pathname, FT_Long face_index, FT_Face *aface) {
+ return FT_New_Face(library, pathname, face_index, aface);
+}
+
+#endif /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */
+
+/* documentation is in freetype.h */
+
+FT_Error __ft_New_Memory_Face(FT_Library library, const FT_Byte* file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface) {
+ FT_Open_Args args;
+
+ /* test for valid `library' and `face' delayed to FT_Open_Face() */
+ if (!file_base)
+ return FT_Err_Invalid_Argument;
+
+ FT_Parameter params[2];
+ params[0].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY;
+ params[0].data = 0;
+ params[1].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY;
+ params[1].data = 0;
+ args.flags = FT_OPEN_MEMORY | FT_OPEN_PARAMS;
+ args.memory_base = file_base;
+ args.memory_size = file_size;
+ args.stream = NULL;
+ args.num_params = 2;
+ args.params = params;
+
+ return FT_Open_Face(library, &args, face_index, aface);
+}
+
+// end
+
QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
{
FT_Library library = qt_getFreetype();
@@ -183,9 +256,11 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
FT_Face face;
FT_Error error;
if (!fontData.isEmpty()) {
- error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
+ // Patch: Enable Open Sans Semibold font family reading.
+ error = __ft_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
} else {
- error = FT_New_Face(library, file.constData(), index, &face);
+ // Patch: Enable Open Sans Semibold font family reading.
+ error = __ft_New_Face(library, file.constData(), index, &face);
}
if (error != FT_Err_Ok) {
qDebug() << "FT_New_Face failed with index" << index << ':' << hex << error;
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 8ebabf3419..7bb8abd0d0 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -375,6 +375,17 @@ static void populateFromPattern(FcPattern *pattern)
familyName = QString::fromUtf8((const char *)value);
+ // Patch: Enable Open Sans Semibold font family reading.
+ if (familyName == QLatin1String("Open Sans")) {
+ FcChar8 *styl = 0;
+ if (FcPatternGetString(pattern, FC_STYLE, 0, &styl) == FcResultMatch) {
+ QString style = QString::fromUtf8(reinterpret_cast<const char *>(styl));
+ if (style == QLatin1String("Semibold")) {
+ familyName.append(QChar(QChar::Space)).append(style);
+ }
+ }
+ }
+
slant_value = FC_SLANT_ROMAN;
weight_value = FC_WEIGHT_REGULAR;
spacing_value = FC_PROPORTIONAL;
@@ -718,7 +729,19 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
continue;
// capitalize(value);
- const QString familyName = QString::fromUtf8((const char *)value);
+
+ // Patch: Enable Open Sans Semibold font family reading.
+ QString familyName = QString::fromUtf8((const char *)value);
+ if (familyName == QLatin1String("Open Sans")) {
+ FcChar8 *styl = 0;
+ if (FcPatternGetString(fontSet->fonts[i], FC_STYLE, 0, &styl) == FcResultMatch) {
+ QString style = QString::fromUtf8(reinterpret_cast<const char *>(styl));
+ if (style == QLatin1String("Semibold")) {
+ familyName.append(QChar(QChar::Space)).append(style);
+ }
+ }
+ }
+
const QString familyNameCF = familyName.toCaseFolded();
if (!duplicates.contains(familyNameCF)) {
fallbackFamilies << familyName;
@@ -784,6 +807,18 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
FcChar8 *fam = 0;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
+
+ // Patch: Enable Open Sans Semibold font family reading.
+ if (family == QLatin1String("Open Sans")) {
+ FcChar8 *styl = 0;
+ if (FcPatternGetString(pattern, FC_STYLE, 0, &styl) == FcResultMatch) {
+ QString style = QString::fromUtf8(reinterpret_cast<const char *>(styl));
+ if (style == QLatin1String("Semibold")) {
+ family.append(QChar(QChar::Space)).append(style);
+ }
+ }
+ }
+
families << family;
}
populateFromPattern(pattern);
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 566abf2126..5c5fde9813 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -265,6 +265,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
fd->foundryName = QStringLiteral("CoreText");
fd->familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
+
+ // Patch: Enable Open Sans Semibold font family reading.
+ 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;
@@ -300,9 +307,10 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
if (styles) {
if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
- float normalizedWeight;
- if (CFNumberGetValue(weightValue, kCFNumberFloatType, &normalizedWeight))
- fd->weight = QCoreTextFontEngine::qtWeightFromCFWeight(normalizedWeight);
+ // Patch: backport bugfix from 'b64ea4a3ab' commit.
+ double normalizedWeight;
+ if (CFNumberGetValue(weightValue, kCFNumberFloat64Type, &normalizedWeight))
+ fd->weight = QCoreTextFontEngine::qtWeightFromCFWeight(float(normalizedWeight));
}
if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
double d;
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 7b459584ea..2ed2fd9b3b 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -764,7 +764,8 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gl
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/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
index 86bdd4729b..9b9c8ded08 100644
--- a/src/plugins/platforminputcontexts/compose/compose.pro
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -15,7 +15,8 @@ HEADERS += $$PWD/qcomposeplatforminputcontext.h \
contains(QT_CONFIG, xkbcommon-qt): {
# dont't need x11 dependency for compose key plugin
QT_CONFIG -= use-xkbcommon-x11support
- include(../../../3rdparty/xkbcommon.pri)
+ # Patch: Adding fcitx input context plugin to our static build.
+ #include(../../../3rdparty/xkbcommon.pri)
} else {
LIBS += $$QMAKE_LIBS_XKBCOMMON
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
index d1bea9af23..36a15a6473 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
@@ -232,6 +232,12 @@ bool QComposeInputContext::checkComposeTable()
void QComposeInputContext::commitText(uint character) const
{
+ // Patch: Crash fix when not focused widget still receives input events.
+ if (!m_focusObject) {
+ qWarning("QComposeInputContext::commitText: m_focusObject == nullptr, cannot commit text");
+ return;
+ }
+
QInputMethodEvent event;
event.setCommitString(QChar(character));
QCoreApplication::sendEvent(m_focusObject, &event);
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
index faea54b874..fe4a837511 100644
--- a/src/plugins/platforminputcontexts/platforminputcontexts.pro
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
@@ -1,7 +1,8 @@
TEMPLATE = subdirs
qtHaveModule(dbus) {
-!mac:!win32:SUBDIRS += ibus
+# Patch: Adding fcitx/hime/nimf input context plugin to our static build.
+!mac:!win32:SUBDIRS += ibus fcitx hime nimf
}
contains(QT_CONFIG, xcb-plugin): SUBDIRS += compose
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index caa8884661..9dc3bc1661 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -210,7 +210,8 @@ QT_END_NAMESPACE
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]) {
@@ -287,11 +288,15 @@ QT_END_NAMESPACE
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
+ // Patch: We need to catch that notification in delegate.
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationDidFinishLaunching:)])
+ [reflectionDelegate applicationDidFinishLaunching:aNotification];
+
Q_UNUSED(aNotification);
inLaunch = false;
// qt_release_apple_event_handler();
-
// Insert code here to initialize your application
}
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 934f68ad18..3ece6984ac 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -64,6 +64,9 @@ public:
private:
QImage m_qImage;
QSize m_requestedSize;
+
+ // Patch: Optimize redraw - don't clear image if it will be fully redrawn.
+ bool m_qImageNeedsClear;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index ca92103826..f27ea15bad 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -38,7 +38,8 @@
QT_BEGIN_NAMESPACE
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
+ // Patch: Optimize redraw - don't clear image if it will be fully redrawn.
+ : QPlatformBackingStore(window), m_qImageNeedsClear(false)
{
}
@@ -59,9 +60,12 @@ QPaintDevice *QCocoaBackingStore::paintDevice()
if (m_qImage.size() != effectiveBufferSize) {
QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient)
? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+
+ // Patch: Optimize redraw - don't clear image if it will be fully redrawn.
+ m_qImageNeedsClear = window()->requestedFormat().hasAlpha() || cocoaWindow->m_drawContentBorderGradient;
m_qImage = QImage(effectiveBufferSize, format);
m_qImage.setDevicePixelRatio(windowDevicePixelRatio);
- if (format == QImage::Format_ARGB32_Premultiplied)
+ if (m_qImageNeedsClear)
m_qImage.fill(Qt::transparent);
}
return &m_qImage;
@@ -100,7 +104,8 @@ bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy)
void QCocoaBackingStore::beginPaint(const QRegion &region)
{
- if (m_qImage.hasAlphaChannel()) {
+ // Patch: Optimize redraw - don't clear image if it will be fully redrawn.
+ if (m_qImageNeedsClear && m_qImage.hasAlphaChannel()) {
QPainter p(&m_qImage);
p.setCompositionMode(QPainter::CompositionMode_Source);
const QVector<QRect> rects = region.rects();
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 058209da7e..6af61e7dab 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -546,9 +546,9 @@ 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);
+// 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));
@@ -557,9 +557,9 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
CGContextDrawImage(inContext, *inBounds, inImage);
CGContextRestoreGState(inContext);
-InvalidImage:
-InvalidBounds:
-InvalidContext:
+//InvalidImage:
+//InvalidBounds:
+//InvalidContext:
return err;
}
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
index c2d206fb45..9b9739862d 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
@@ -384,6 +384,12 @@ bool QCocoaKeyMapper::updateKeyboard()
keyboardInputLocale = QLocale::c();
keyboardInputDirection = Qt::LeftToRight;
}
+
+ // Patch: Fix layout-independent global shortcuts.
+ const auto newMode = keyboard_mode;
+ deleteLayouts();
+ keyboard_mode = newMode;
+
return true;
}
@@ -466,7 +472,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: Fix layout-independent global shortcuts.
+ ret << int(key + neededMods);
}
}
return ret;
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 8152c57ffd..87ba2f3f72 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -94,6 +94,8 @@ QT_USE_NAMESPACE
QCocoaSystemTrayIcon *systray;
NSStatusItem *item;
QCocoaMenu *menu;
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ bool menuVisible, iconSelected;
QIcon icon;
QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
}
@@ -197,7 +199,9 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
// (device independent pixels). The menu height on past and
// current OS X versions is 22 points. Provide some future-proofing
// by deriving the icon height from the menu height.
- const int padding = 4;
+
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ const int padding = 0;
const int menuHeight = [[NSStatusBar systemStatusBar] thickness];
const int maxImageHeight = menuHeight - padding;
@@ -207,8 +211,11 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
// devicePixelRatio for the "best" screen on the system.
qreal devicePixelRatio = qApp->devicePixelRatio();
const int maxPixmapHeight = maxImageHeight * devicePixelRatio;
+
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ const QIcon::Mode mode = m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal;
QSize selectedSize;
- Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes())) {
+ Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) {
// Select a pixmap based on the height. We want the largest pixmap
// with a height smaller or equal to maxPixmapHeight. The pixmap
// may rectangular; assume it has a reasonable size. If there is
@@ -224,9 +231,9 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
// Handle SVG icons, which do not return anything for availableSizes().
if (!selectedSize.isValid())
- selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight));
+ selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight), mode);
- QPixmap pixmap = icon.pixmap(selectedSize);
+ QPixmap pixmap = icon.pixmap(selectedSize, mode);
// Draw a low-resolution icon if there is not enough pixels for a retina
// icon. This prevents showing a small icon on retina displays.
@@ -374,6 +381,11 @@ QT_END_NAMESPACE
Q_UNUSED(notification);
down = NO;
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ parent->iconSelected = false;
+ parent->systray->updateIcon(parent->icon);
+ parent->menuVisible = false;
+
[self setNeedsDisplay:YES];
}
@@ -383,6 +395,10 @@ QT_END_NAMESPACE
int clickCount = [mouseEvent clickCount];
[self setNeedsDisplay:YES];
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ parent->iconSelected = (clickCount != 2) && parent->menu;
+ parent->systray->updateIcon(parent->icon);
+
if (clickCount == 2) {
[self menuTrackingDone:nil];
[parent doubleClickSelector:self];
@@ -399,6 +415,11 @@ QT_END_NAMESPACE
-(void)mouseUp:(NSEvent *)mouseEvent
{
Q_UNUSED(mouseEvent);
+
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ parent->iconSelected = false;
+ parent->systray->updateIcon(parent->icon);
+
[self menuTrackingDone:nil];
}
@@ -410,6 +431,11 @@ QT_END_NAMESPACE
-(void)rightMouseUp:(NSEvent *)mouseEvent
{
Q_UNUSED(mouseEvent);
+
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ parent->iconSelected = false;
+ parent->systray->updateIcon(parent->icon);
+
[self menuTrackingDone:nil];
}
@@ -425,7 +451,8 @@ QT_END_NAMESPACE
}
-(void)drawRect:(NSRect)rect {
- [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down];
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO];
[super drawRect:rect];
}
@end
@@ -438,6 +465,10 @@ QT_END_NAMESPACE
if (self) {
item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
menu = 0;
+
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ menuVisible = false;
+
systray = sys;
imageCell = [[QNSImageView alloc] initWithParent:self];
[item setView: imageCell];
2018-09-26 10:18:29 +00:00
@@ -448,6 +479,11 @@ QT_END_NAMESPACE
-(void)dealloc {
[[NSStatusBar systemStatusBar] removeStatusItem:item];
[[NSNotificationCenter defaultCenter] removeObserver:imageCell];
+
+ // Patch: Fix crash in macOS 10.14.
+ // Somehow item and imageCell are retained and attempt to be drawn if left in view.
+ [item setView: nil];
+
[imageCell release];
[item release];
[super dealloc];
@@ -482,6 +518,10 @@ QT_END_NAMESPACE
selector:@selector(menuTrackingDone:)
name:NSMenuDidEndTrackingNotification
object:m];
+
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ menuVisible = true;
+
[item popUpStatusItemMenu: m];
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index c0d5904367..f3c2047196 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -141,7 +141,8 @@ static bool isMouseEvent(NSEvent *ev)
if (!self.window.delegate)
return; // Already detached, pending NSAppKitDefined event
- if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
+ // Patch: Fix restore after minimize or close by window buttons.
+ if (pw && pw->frameStrutEventsEnabled() && pw->m_synchedWindowState != Qt::WindowMinimized && pw->m_isExposed && isMouseEvent(theEvent)) {
NSPoint loc = [theEvent locationInWindow];
NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
NSRect contentFrame = [[self.window contentView] frame];
@@ -811,6 +812,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) {
@@ -943,6 +954,19 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
[m_nsWindow setRepresentedFilename: fi.exists() ? QCFString::toNSString(filePath) : @""];
}
+// Patch: Create a good os x window icon (pixel-perfect).
+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)
{
QMacAutoReleasePool pool;
@@ -958,7 +982,9 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
if (icon.isNull()) {
[iconButton setImage:nil];
} else {
- QPixmap pixmap = icon.pixmap(QSize(22, 22));
+ // Patch: Create a good os x window icon (pixel-perfect).
+ 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 c67bcfd23b..6a60670aee 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -647,6 +647,12 @@ QT_WARNING_POP
[self invalidateWindowShadowIfNeeded];
}
+- (void)viewDidChangeBackingProperties
+{
+ if (self.layer)
+ self.layer.contentsScale = self.window.backingScaleFactor;
+}
+
- (BOOL) isFlipped
{
return YES;
@@ -1431,7 +1437,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: Fix actual begin handle of swipe on trackpad.
+ if (phase == NSEventPhaseMayBegin || phase == NSEventPhaseBegan) {
m_scrolling = true;
ph = Qt::ScrollBegin;
}
@@ -1496,14 +1504,14 @@ 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: Fix Alt+.. shortcuts in OS X. See https://bugreports.qt.io/browse/QTBUG-42584 at the end.
+ if ([characters length] != 0)
+ 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];
// we will send a key event unless the input method sets m_sendKeyEvent to false
m_sendKeyEvent = true;
@@ -1569,6 +1577,23 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)];
}
+// Patch: Enable Ctrl+Tab and Ctrl+Shift+Tab / Ctrl+Backtab handle in-app.
+- (BOOL)performKeyEquivalent:(NSEvent *)nsevent
+{
+ NSString *chars = [nsevent charactersIgnoringModifiers];
+
+ if ([nsevent type] == NSKeyDown && [chars length] > 0) {
+ QChar ch = [chars characterAtIndex:0];
+ Qt::Key qtKey = qt_mac_cocoaKey2QtKey(ch);
+ 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];
+}
+
- (void)cancelOperation:(id)sender
{
Q_UNUSED(sender);
@@ -1981,6 +2006,10 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
// change the cursor
[nativeCursor set];
+ // Patch: Backport a fix from cd08753d3e. Starting with macOS Mojave this requires accessibility access.
+ if (QSysInfo::macVersion() >= Q_MV_OSX(10, 14))
+ return;
+
// Make sure the cursor is updated correctly if the mouse does not move and window is under cursor
// by creating a fake move event
if (m_updatingDrag)
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 94bb71e429..16ab51e166 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -716,12 +716,20 @@ public:
void setSelectedFiles(const QList<QUrl> &);
QString selectedFile() const;
+ // Patch: Adding select-by-url for Windows file dialog.
+ void setSelectedRemoteContent(const QByteArray &);
+ QByteArray selectedRemoteContent() const;
+
private:
class Data : public QSharedData {
public:
QUrl directory;
QString selectedNameFilter;
QList<QUrl> selectedFiles;
+
+ // Patch: Adding select-by-url for Windows file dialog.
+ QByteArray selectedRemoteContent;
+
QMutex mutex;
};
QExplicitlySharedDataPointer<Data> m_data;
@@ -775,6 +783,21 @@ inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &ur
m_data->selectedFiles = urls;
}
+// Patch: Adding select-by-url for Windows file dialog.
+inline QByteArray QWindowsFileDialogSharedData::selectedRemoteContent() const
+{
+ m_data->mutex.lock();
+ const QByteArray result = m_data->selectedRemoteContent;
+ m_data->mutex.unlock();
+ return result;
+}
+
+inline void QWindowsFileDialogSharedData::setSelectedRemoteContent(const QByteArray &c)
+{
+ QMutexLocker(&m_data->mutex);
+ m_data->selectedRemoteContent = c;
+}
+
inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFileDialogOptions> &o)
{
QMutexLocker locker(&m_data->mutex);
@@ -899,6 +922,9 @@ public:
// example by appended default suffixes, etc.
virtual QList<QUrl> dialogResult() const = 0;
+ // Patch: Adding select-by-url for Windows file dialog.
+ virtual QByteArray dialogRemoteContent() const { return QByteArray(); }
+
inline void onFolderChange(IShellItem *);
inline void onSelectionChange();
inline void onTypeChange();
@@ -1338,7 +1364,14 @@ void QWindowsNativeFileDialogBase::selectFile(const QString &fileName) const
// Hack to prevent CLSIDs from being set as file name due to
// QFileDialogPrivate::initialSelection() being QString-based.
if (!isClsid(fileName))
- m_fileDialog->SetFileName((wchar_t*)fileName.utf16());
+ // Patch: Fix handle of full fileName.
+ {
+ QString file = QDir::toNativeSeparators(fileName);
+ int lastBackSlash = file.lastIndexOf(QChar::fromLatin1('\\'));
+ if (lastBackSlash >= 0)
+ file = file.mid(lastBackSlash + 1);
+ m_fileDialog->SetFileName((wchar_t*)file.utf16());;
+ }
}
// Return the index of the selected filter, accounting for QFileDialog
@@ -1408,6 +1441,10 @@ bool QWindowsNativeFileDialogBase::onFileOk()
{
// Store selected files as GetResults() returns invalid data after the dialog closes.
m_data.setSelectedFiles(dialogResult());
+
+ // Patch: Adding select-by-url for Windows file dialog.
+ m_data.setSelectedRemoteContent(dialogRemoteContent());
+
return true;
}
@@ -1542,6 +1579,9 @@ public:
QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
QList<QUrl> dialogResult() const Q_DECL_OVERRIDE;
+ // Patch: Adding select-by-url for Windows file dialog.
+ QByteArray dialogRemoteContent() const Q_DECL_OVERRIDE;
+
private:
inline IFileOpenDialog *openFileDialog() const
{ return static_cast<IFileOpenDialog *>(fileDialog()); }
@@ -1556,6 +1596,62 @@ QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
return result;
}
+// Patch: Adding select-by-url for Windows file dialog.
+QByteArray QWindowsNativeOpenFileDialog::dialogRemoteContent() const
+{
+ QByteArray result;
+ IShellItemArray *items = 0;
+ if (FAILED(openFileDialog()->GetResults(&items)) || !items)
+ return result;
+ DWORD itemCount = 0;
+ if (FAILED(items->GetCount(&itemCount)) || !itemCount)
+ return result;
+ for (DWORD i = 0; i < itemCount; ++i)
+ {
+ IShellItem *item = 0;
+ if (SUCCEEDED(items->GetItemAt(i, &item))) {
+ SFGAOF attributes = 0;
+ // Check whether it has a file system representation?
+ if (FAILED(item->GetAttributes(SFGAO_FILESYSTEM, &attributes)) || (attributes & SFGAO_FILESYSTEM))
+ {
+ LPWSTR name = 0;
+ if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &name)))
+ {
+ CoTaskMemFree(name);
+ continue;
+ }
+ }
+ if (FAILED(item->GetAttributes(SFGAO_STREAM, &attributes)) || !(attributes & SFGAO_STREAM))
+ continue;
+
+ IBindCtx *bind = 0;
+ if (FAILED(CreateBindCtx(0, &bind)))
+ continue;
+
+ IStream *stream = 0;
+ if (FAILED(item->BindToHandler(bind, BHID_Stream, IID_IStream, reinterpret_cast<void **>(&stream))))
+ continue;
+
+ STATSTG stat = { 0 };
+ if (FAILED(stream->Stat(&stat, STATFLAG_NONAME)) || !stat.cbSize.QuadPart)
+ continue;
+
+ quint64 fullSize = stat.cbSize.QuadPart;
+ if (fullSize <= 64 * 1024 * 1024)
+ {
+ result.resize(fullSize);
+ ULONG read = 0;
+ HRESULT r = stream->Read(result.data(), fullSize, &read);
+ if (r == S_FALSE || r == S_OK)
+ return result;
+
+ result.clear();
+ }
+ }
+ }
+ return result;
+}
+
QList<QUrl> QWindowsNativeOpenFileDialog::selectedFiles() const
{
QList<QUrl> result;
@@ -1614,6 +1710,10 @@ public:
virtual QUrl directory() const Q_DECL_OVERRIDE;
virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+
+ // Patch: Adding select-by-url for Windows file dialog.
+ virtual QByteArray selectedRemoteContent() const Q_DECL_OVERRIDE;
+
virtual void setFilter() Q_DECL_OVERRIDE;
virtual void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE;
virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
@@ -1707,6 +1807,12 @@ QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
return m_data.selectedFiles();
}
+// Patch: Adding select-by-url for Windows file dialog.
+QByteArray QWindowsFileDialogHelper::selectedRemoteContent() const
+{
+ return m_data.selectedRemoteContent();
+}
+
void QWindowsFileDialogHelper::setFilter()
{
qCDebug(lcQpaDialogs) << __FUNCTION__;
@@ -1996,6 +2102,10 @@ public:
QUrl directory() const Q_DECL_OVERRIDE;
void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+
+ // Patch: Adding select-by-url for Windows file dialog.
+ QByteArray selectedRemoteContent() const Q_DECL_OVERRIDE;
+
void setFilter() Q_DECL_OVERRIDE {}
void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
QString selectedNameFilter() const Q_DECL_OVERRIDE;
@@ -2039,6 +2149,12 @@ QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
return m_data.selectedFiles();
}
+// Patch: Adding select-by-url for Windows file dialog.
+QByteArray QWindowsXpFileDialogHelper::selectedRemoteContent() const
+{
+ return m_data.selectedRemoteContent();
+}
+
void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f)
{
m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time.
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 1e58b9b3d4..1741c21a1c 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -1268,6 +1268,10 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
if (nativeVirtualKey > 255)
return result;
+ // Patch: This must not happen, but there are crash reports on the next line.
+ if (e->nativeVirtualKey() > 0xFF)
+ return result;
+
const KeyboardLayoutItem &kbItem = keyLayout[nativeVirtualKey];
if (!kbItem.exists)
return result;
diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp
index 1d23a9d9b9..640cd426ed 100644
--- a/src/plugins/platforms/windows/qwindowsservices.cpp
+++ b/src/plugins/platforms/windows/qwindowsservices.cpp
@@ -127,6 +127,10 @@ static inline bool launchMail(const QUrl &url)
command.prepend(doubleQuote);
}
}
+
+ // Patch: Fix mail launch if no param is expected in this command.
+ if (command.indexOf(QStringLiteral("%1")) < 0) return false;
+
// Pass the url as the parameter. Should use QProcess::startDetached(),
// but that cannot handle a Windows command line [yet].
command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded));
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index b38d7c29ae..34f19c4efa 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1020,7 +1020,8 @@ void QWindowsWindow::destroyWindow()
// Clear any transient child relationships as Windows will otherwise destroy them (QTBUG-35499, QTBUG-36666)
if (QWindow *transientChild = findTransientChild(window()))
if (QWindowsWindow *tw = QWindowsWindow::baseWindowOf(transientChild))
- tw->updateTransientParent();
+ // Patch: Fix possibility of add / remove taskbar icon of the window.
+ tw->clearTransientParent();
QWindowsContext *context = QWindowsContext::instance();
if (context->windowUnderMouse() == window())
context->clearWindowUnderMouse();
@@ -1235,6 +1236,21 @@ void QWindowsWindow::updateTransientParent() const
if (const QWindowsWindow *tw = QWindowsWindow::baseWindowOf(tp))
if (!tw->testFlag(WithinDestroy)) // Prevent destruction by parent window (QTBUG-35499, QTBUG-36666)
newTransientParent = tw->handle();
+ // Patch: Fix possibility of add / remove taskbar icon of the window.
+ if (newTransientParent && newTransientParent != oldTransientParent)
+ SetWindowLongPtr(m_data.hwnd, GWL_HWNDPARENT, (LONG_PTR)newTransientParent);
+#endif // !Q_OS_WINCE
+}
+
+// Patch: Fix possibility of add / remove taskbar icon of the window.
+void QWindowsWindow::clearTransientParent() const
+{
+#ifndef Q_OS_WINCE
+ if (window()->type() == Qt::Popup)
+ return; // QTBUG-34503, // a popup stays on top, no parent, see also WindowCreationData::fromWindow().
+ // Update transient parent.
+ const HWND oldTransientParent = transientParentHwnd(m_data.hwnd);
+ HWND newTransientParent = 0;
if (newTransientParent != oldTransientParent)
SetWindowLongPtr(m_data.hwnd, GWL_HWNDPARENT, (LONG_PTR)newTransientParent);
#endif // !Q_OS_WINCE
@@ -1448,10 +1464,14 @@ void QWindowsWindow::handleResized(int wParam)
handleGeometryChange();
break;
case SIZE_RESTORED:
- if (isFullScreen_sys())
- handleWindowStateChange(Qt::WindowFullScreen);
- else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
+ // Patch: When resolution is changed for a frameless fullscreen widget
+ // handleWindowStateChange call prevents correct geometry get in handleGeometryChange().
+ if (isFullScreen_sys()) {
+ if (m_windowState != Qt::WindowFullScreen)
+ handleWindowStateChange(Qt::WindowFullScreen);
+ } else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen)) {
handleWindowStateChange(Qt::WindowNoState);
+ }
handleGeometryChange();
break;
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 6fffa1e6e9..cb1c9c1161 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -265,6 +265,10 @@ private:
inline void setWindowState_sys(Qt::WindowState newState);
inline void setParent_sys(const QPlatformWindow *parent);
inline void updateTransientParent() const;
+
+ // Patch: Fix possibility of add / remove taskbar icon of the window.
+ inline void clearTransientParent() const;
+
void destroyWindow();
inline bool isDropSiteEnabled() const { return m_dropTarget != 0; }
void setDropSiteEnabled(bool enabled);
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 09e7ecf3a3..c0f15a4242 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -79,7 +79,10 @@ static int resourceType(const QByteArray &key)
QByteArrayLiteral("rootwindow"),
QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingenabled"),
QByteArrayLiteral("nofonthinting"),
- QByteArrayLiteral("atspibus")
+ QByteArrayLiteral("atspibus"),
+
+ // Patch: Backport compositing manager check from Qt 5.7
+ QByteArrayLiteral("compositingenabled")
};
const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
const QByteArray *result = std::find(names, end, key);
@@ -252,6 +255,13 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resourceStr
case RootWindow:
result = reinterpret_cast<void *>(xcbScreen->root());
break;
+
+ // Patch: Backport compositing manager check from Qt 5.7
+ case CompositingEnabled:
+ if (QXcbVirtualDesktop *vd = xcbScreen->virtualDesktop())
+ result = vd->compositingActive() ? this : Q_NULLPTR;
+ break;
+
default:
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index f88b710864..6f818a5a72 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -68,7 +68,10 @@ public:
ScreenSubpixelType,
ScreenAntialiasingEnabled,
NoFontHinting,
- AtspiBus
+ AtspiBus,
+
+ // Patch: Backport compositing manager check from Qt 5.7
+ CompositingEnabled
};
QXcbNativeInterface();
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index bc2de899f5..aa8f8df4ad 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1200,6 +1200,15 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
return files;
}
+// Patch: Adding select-by-url for Windows file dialog.
+QByteArray QFileDialogPrivate::userSelectedRemoteContent() const
+{
+ if (nativeDialogInUse)
+ return selectedRemoteContent_sys();
+
+ return QByteArray();
+}
+
QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList &filesToFix) const
{
QStringList files;
@@ -1267,6 +1276,14 @@ QStringList QFileDialog::selectedFiles() const
return files;
}
+// Patch: Adding select-by-url for Windows file dialog.
+QByteArray QFileDialog::selectedRemoteContent() const
+{
+ Q_D(const QFileDialog);
+
+ return d->userSelectedRemoteContent();
+}
+
/*!
Returns a list of urls containing the selected files in the dialog.
If no files are selected, or the mode is not ExistingFiles or
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
index ffe49a2dd2..42dc563c8a 100644
--- a/src/widgets/dialogs/qfiledialog.h
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -108,6 +108,9 @@ public:
void selectFile(const QString &filename);
QStringList selectedFiles() const;
+ // Patch: Adding select-by-url for Windows file dialog.
+ QByteArray selectedRemoteContent() const;
+
void selectUrl(const QUrl &url);
QList<QUrl> selectedUrls() const;
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index f610e46f83..547a64695a 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -123,6 +123,10 @@ public:
static QString initialSelection(const QUrl &path);
QStringList typedFiles() const;
QList<QUrl> userSelectedFiles() const;
+
+ // Patch: Adding select-by-url for Windows file dialog.
+ QByteArray userSelectedRemoteContent() const;
+
QStringList addDefaultSuffixToFiles(const QStringList &filesToFix) const;
QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
bool removeDirectory(const QString &path);
@@ -256,6 +260,10 @@ public:
QUrl directory_sys() const;
void selectFile_sys(const QUrl &filename);
QList<QUrl> selectedFiles_sys() const;
+
+ // Patch: Adding select-by-url for Windows file dialog.
+ QByteArray selectedRemoteContent_sys() const;
+
void setFilter_sys();
void selectNameFilter_sys(const QString &filter);
QString selectedNameFilter_sys() const;
@@ -393,6 +401,14 @@ inline QList<QUrl> QFileDialogPrivate::selectedFiles_sys() const
return QList<QUrl>();
}
+// Patch: Adding select-by-url for Windows file dialog.
+inline QByteArray QFileDialogPrivate::selectedRemoteContent_sys() const
+{
+ if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
+ return helper->selectedRemoteContent();
+ return QByteArray();
+}
+
inline void QFileDialogPrivate::setFilter_sys()
{
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index b1d80d7b8f..42e32fd404 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -5138,6 +5138,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;
@@ -5159,6 +5170,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;
}
@@ -5190,6 +5205,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)
@@ -8769,7 +8787,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: Enable Ctrl+Tab and Ctrl+Shift+Tab / Ctrl+Backtab handle in-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/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 704142fe5c..7c4340e459 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -709,6 +709,10 @@ void QSystemTrayIconPrivate::updateMenu_sys_qpa()
if (menu) {
addPlatformMenu(menu);
qpa_sys->updateMenu(menu->platformMenu());
+
+ // Patch: Create a rich os x tray icon (pixel-perfect, theme switching).
+ } else {
+ qpa_sys->updateMenu(nullptr);
}
}
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 2e2a042bf1..472e37722b 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -640,15 +640,22 @@ scrolling range.
QSize QAbstractScrollArea::maximumViewportSize() const
{
Q_D(const QAbstractScrollArea);
- int hsbExt = d->hbar->sizeHint().height();
- int vsbExt = d->vbar->sizeHint().width();
+ // Patch: Count the sizeHint of the bar only if it is displayed.
+ //int hsbExt = d->hbar->sizeHint().height();
+ //int vsbExt = d->vbar->sizeHint().width();
int f = 2 * d->frameWidth;
QSize max = size() - QSize(f + d->left + d->right, f + d->top + d->bottom);
- if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
+
+ // Patch: Count the sizeHint of the bar only if it is displayed.
+ if (d->vbarpolicy == Qt::ScrollBarAlwaysOn) {
+ int vsbExt = d->vbar->sizeHint().width();
max.rwidth() -= vsbExt;
- if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
+ }
+ if (d->hbarpolicy == Qt::ScrollBarAlwaysOn) {
+ int hsbExt = d->hbar->sizeHint().height();
max.rheight() -= hsbExt;
+ }
return max;
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index daf9f00c46..57499dc4a4 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -40,6 +40,11 @@
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
#include <qstylehints.h>
+
+// Patch: Enable Ctrl+key and Ctrl+Shift+key in all locales except German.
+// See https://github.com/telegramdesktop/tdesktop/pull/1185.
+#include <QtCore/QLocale>
+
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif
@@ -1882,11 +1887,21 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
}
// QTBUG-35734: ignore Ctrl/Ctrl+Shift; accept only AltGr (Alt+Ctrl) on German keyboards
- if (unknown && !isReadOnly()
- && event->modifiers() != Qt::ControlModifier
- && event->modifiers() != (Qt::ControlModifier | Qt::ShiftModifier)) {
+
+ // Patch: Enable Ctrl+key and Ctrl+Shift+key in all locales except German.
+ // See https://github.com/telegramdesktop/tdesktop/pull/1185.
+ bool skipCtrlAndCtrlShift = false;
+ if (QGuiApplication::inputMethod()->locale().language() == QLocale::German) {
+ if (event->modifiers() == Qt::ControlModifier
+ || event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) {
+ skipCtrlAndCtrlShift = true;
+ }
+ }
+ if (unknown && !isReadOnly() && !skipCtrlAndCtrlShift) {
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 deca002bf5..8a2023f503 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -71,6 +71,11 @@
#include <qinputmethod.h>
#include <qtooltip.h>
#include <qstyleoption.h>
+
+// Patch: Enable Ctrl+key and Ctrl+Shift+key in all locales except German.
+// See https://github.com/telegramdesktop/tdesktop/pull/1185.
+#include <QtCore/QLocale>
+
#include <QtWidgets/qlineedit.h>
#include <QtGui/qaccessible.h>
#include <QtCore/qmetaobject.h>
@@ -1343,13 +1348,24 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
process:
{
// QTBUG-35734: ignore Ctrl/Ctrl+Shift; accept only AltGr (Alt+Ctrl) on German keyboards
- if (e->modifiers() == Qt::ControlModifier
- || e->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) {
+
+ // Patch: Enable Ctrl+key and Ctrl+Shift+key in all locales except German.
+ // See https://github.com/telegramdesktop/tdesktop/pull/1185.
+ bool skipCtrlAndCtrlShift = false;
+ if (QGuiApplication::inputMethod()->locale().language() == QLocale::German) {
+ if (e->modifiers() == Qt::ControlModifier
+ || e->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) {
+ skipCtrlAndCtrlShift = true;
+ }
+ }
+ if (skipCtrlAndCtrlShift) {
e->ignore();
return;
}
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