Merge "Merge remote-tracking branch 'origin/5.13' into dev"

This commit is contained in:
Liang Qi 2019-07-01 10:21:37 +02:00
commit 57fccd6f21
40 changed files with 328 additions and 129 deletions

View File

@ -64,9 +64,9 @@ void NorwegianWoodStyle::polish(QPalette &palette)
QColor beige(236, 182, 120);
QColor slightlyOpaqueBlack(0, 0, 0, 63);
QPixmap backgroundImage(":/images/woodbackground.png");
QPixmap buttonImage(":/images/woodbutton.png");
QPixmap midImage = buttonImage;
QImage backgroundImage(":/images/woodbackground.png");
QImage buttonImage(":/images/woodbutton.png");
QImage midImage = buttonImage.convertToFormat(QImage::Format_RGB32);
QPainter painter;
painter.begin(&midImage);
@ -311,11 +311,12 @@ void NorwegianWoodStyle::drawControl(ControlElement element,
//! [37]
void NorwegianWoodStyle::setTexture(QPalette &palette, QPalette::ColorRole role,
//! [37] //! [38]
const QPixmap &pixmap)
const QImage &image)
{
for (int i = 0; i < QPalette::NColorGroups; ++i) {
QColor color = palette.brush(QPalette::ColorGroup(i), role).color();
palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap));
QBrush brush(image);
brush.setColor(palette.brush(QPalette::ColorGroup(i), role).color());
palette.setBrush(QPalette::ColorGroup(i), role, brush);
}
}
//! [38]

View File

@ -80,7 +80,7 @@ public:
private:
static void setTexture(QPalette &palette, QPalette::ColorRole role,
const QPixmap &pixmap);
const QImage &image);
static QPainterPath roundRectPath(const QRect &rect);
};
//! [0]

View File

@ -31,7 +31,7 @@ QMAKE_LIBS_OPENGL_ES2 = $${VC_LINK_LINE} -lGLESv2
# The official opt vc EGL references GLESv2 symbols: need to link it
QMAKE_LIBS_EGL = $${VC_LINK_LINE} -lEGL -lGLESv2
QMAKE_LIBDIR_BCM_HOST = $$VC_LIBRARY_PATH
QMAKE_LIBDIR_BCM_HOST = =$$VC_LIBRARY_PATH
QMAKE_INCDIR_BCM_HOST = $$VC_INCLUDE_PATH
QMAKE_LIBS_BCM_HOST = -lbcm_host

View File

@ -0,0 +1,6 @@
load(spec_post)
# Work around idiosyncracy in Android NDK's make executable
# which tries to call the shell-builtin "move" as direct process
equals(QMAKE_HOST.os, Windows):equals(QMAKE_MOVE, move): \
QMAKE_MOVE = cmd /c move

View File

@ -291,6 +291,12 @@ load(qt_targets)
QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0))$$qtPlatformTargetSuffix()
isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \
QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module
!isEmpty(lib_replace0.match) {
pclib_replace0.match = $$lib_replace0.match
pclib_replace0.replace = $$QMAKE_PKGCONFIG_LIBDIR/
pclib_replace0.CONFIG = path
QMAKE_PKGCONFIG_INSTALL_REPLACE += pclib_replace0
}
pclib_replace.match = $$lib_replace.match
!isEmpty(lib_replace.replace): \
pclib_replace.replace = $$QMAKE_PKGCONFIG_LIBDIR
@ -303,6 +309,12 @@ load(qt_targets)
QMAKE_LIBTOOL_LIBDIR = $$[QT_HOST_LIBS]
else: \
QMAKE_LIBTOOL_LIBDIR = "=$$[QT_INSTALL_LIBS/raw]"
!isEmpty(lib_replace0.match) {
ltlib_replace0.match = $$lib_replace0.match
ltlib_replace0.replace = $$QMAKE_LIBTOOL_LIBDIR/
ltlib_replace0.CONFIG = path
QMAKE_LIBTOOL_INSTALL_REPLACE += ltlib_replace0
}
ltlib_replace.match = $$lib_replace.match
!isEmpty(lib_replace.replace): \
ltlib_replace.replace = $$QMAKE_LIBTOOL_LIBDIR

View File

@ -504,6 +504,10 @@ EGLint SwapChain11::resize(const gl::Context *context,
ASSERT(SUCCEEDED(result));
if (SUCCEEDED(result))
{
#ifndef ANGLE_ENABLE_WINDOWS_STORE
if (mNativeWindow->getNativeWindow())
InvalidateRect(mNativeWindow->getNativeWindow(), nullptr, FALSE);
#endif
const auto &format =
d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
mBackBufferTexture.set(backbufferTexture, format);

View File

@ -36,7 +36,7 @@ android {
compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion
buildToolsVersion '28.0.3'
sourceSets {
main {

View File

@ -0,0 +1,37 @@
From 7d300c6e7d05f4e31c966f1298d11da3eae9d679 Mon Sep 17 00:00:00 2001
From: Val Doroshchuk <valentyn.doroshchuk@qt.io>
Date: Fri, 21 Jun 2019 11:24:06 +0200
Subject: [PATCH] ANGLE: Invalidate client window area when resizing swap chain
Inspired by:
https://codereview.appspot.com/6812076/
Resizing a window larger results in the newly exposed region being invalidated
but the old region is treated as valid.
This can result in the old region no longer updating.
Was added to D3D9.
Improving a fix from Filippo Cucchetto:
https://codereview.qt-project.org/c/qt/qtbase/+/195336
and pushing to D3D11.
ifndef protects against compilation error for WinRT.
Invalidate() should be used only for desktop apps.
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
index dcfd06484d..e8f13b388f 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -504,6 +504,10 @@ EGLint SwapChain11::resize(const gl::Context *context,
ASSERT(SUCCEEDED(result));
if (SUCCEEDED(result))
{
+#ifndef ANGLE_ENABLE_WINDOWS_STORE
+ if (mNativeWindow->getNativeWindow())
+ InvalidateRect(mNativeWindow->getNativeWindow(), nullptr, FALSE);
+#endif
const auto &format =
d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
mBackBufferTexture.set(backbufferTexture, format);
--
2.14.2.windows.1

View File

@ -445,3 +445,5 @@ void QTransposeProxyModel::sort(int column, Qt::SortOrder order)
}
QT_END_NAMESPACE
#include "moc_qtransposeproxymodel.cpp"

View File

@ -948,11 +948,8 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
end:
if (!tn)
return QString();
QString str = QString((const QChar *)tn, tn_length/2);
if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
QChar *data = str.data();
qbswap<sizeof(QChar)>(data, str.length(), data);
}
QString str(tn_length / 2, Qt::Uninitialized);
qFromBigEndian<ushort>(tn, str.length(), str.data());
return str;
}

View File

@ -242,8 +242,8 @@ private:
template <typename FP> FP _toFloatingPoint() const noexcept
{
using UInt = typename QIntegerForSizeof<FP>::Unsigned;
UInt u = UInt(value64);
using UIntFP = typename QIntegerForSizeof<FP>::Unsigned;
UIntFP u = UIntFP(value64);
FP f;
memcpy(static_cast<void *>(&f), &u, sizeof(f));
return f;

View File

@ -43,6 +43,7 @@
#include "qjsonwriter_p.h"
#include "qjson_p.h"
#include "private/qutfcodec_p.h"
#include <private/qnumeric_p.h>
QT_BEGIN_NAMESPACE
@ -135,8 +136,9 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value &
case QJsonValue::Double: {
const double d = v.toDouble(b);
if (qIsFinite(d)) { // +2 to format to ensure the expected precision
const double abs = std::abs(d);
json += QByteArray::number(d, abs == static_cast<quint64>(abs) ? 'f' : 'g', QLocale::FloatingPointShortest);
quint64 absInt;
json += QByteArray::number(d, convertDoubleTo(std::abs(d), &absInt) ? 'f' : 'g',
QLocale::FloatingPointShortest);
} else {
json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
}

View File

@ -943,6 +943,23 @@ QByteArray qUncompress(const uchar* data, int nbytes)
and QByteArray() compares equal to QByteArray(""). We recommend
that you always use isEmpty() and avoid isNull().
\section1 Maximum size and out-of-memory conditions
The current version of QByteArray is limited to just under 2 GB (2^31
bytes) in size. The exact value is architecture-dependent, since it depends
on the overhead required for managing the data block, but is no more than
32 bytes. Raw data blocks are also limited by the use of \c int type in the
current version to 2 GB minus 1 byte.
In case memory allocation fails, QByteArray will throw a \c std::bad_alloc
exception. Out of memory conditions in the Qt containers are the only case
where Qt will throw exceptions.
Note that the operating system may impose further limits on applications
holding a lot of allocated memory, especially large, contiguous blocks.
Such considerations, the configuration of such behavior or any mitigation
are outside the scope of the QByteArray API.
\section1 Notes on Locale
\section2 Number-String Conversions

View File

@ -115,11 +115,11 @@ template <class Key, class T> \
class Q##C##Iterator \
{ \
typedef typename Q##C<Key,T>::const_iterator const_iterator; \
typedef const_iterator Item; \
Q##C<Key,T> c; \
const_iterator i, n; \
inline bool item_exists() const { return n != c.constEnd(); } \
public: \
typedef const_iterator Item; \
inline Q##C##Iterator(const Q##C<Key,T> &container) \
: c(container), i(c.constBegin()), n(c.constEnd()) {} \
inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
@ -148,11 +148,11 @@ class QMutable##C##Iterator \
{ \
typedef typename Q##C<Key,T>::iterator iterator; \
typedef typename Q##C<Key,T>::const_iterator const_iterator; \
typedef iterator Item; \
Q##C<Key,T> *c; \
iterator i, n; \
inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
public: \
typedef iterator Item; \
inline QMutable##C##Iterator(Q##C<Key,T> &container) \
: c(&container) \
{ i = c->begin(); n = c->end(); } \

View File

@ -1739,6 +1739,24 @@ const QString::Null QString::null = { };
and the \c{'+'} will automatically be performed as the
\c{QStringBuilder} \c{'%'} everywhere.
\section1 Maximum size and out-of-memory conditions
The current version of QString is limited to just under 2 GB (2^31 bytes)
in size. The exact value is architecture-dependent, since it depends on the
overhead required for managing the data block, but is no more than 32
bytes. Raw data blocks are also limited by the use of \c int type in the
current version to 2 GB minus 1 byte. Since QString uses two bytes per
character, that translates to just under 2^30 characters in one QString.
In case memory allocation fails, QString will throw a \c std::bad_alloc
exception. Out of memory conditions in the Qt containers are the only case
where Qt will throw exceptions.
Note that the operating system may impose further limits on applications
holding a lot of allocated memory, especially large, contiguous blocks.
Such considerations, the configuration of such behavior or any mitigation
are outside the scope of the Qt API.
\sa fromRawData(), QChar, QLatin1String, QByteArray, QStringRef
*/

View File

@ -173,6 +173,24 @@
For a detailed discussion comparing Qt containers with each other and
with STL containers, see \l {Understand the Qt Containers}.
\section1 Maximum size and out-of-memory conditions
The current version of QVector is limited to just under 2 GB (2^31 bytes)
in size. The exact value is architecture-dependent, since it depends on the
overhead required for managing the data block, but is no more than 32
bytes. The number of elements that can be stored in a QVector is that size
divided by the size of each element.
In case memory allocation fails, QVector will use the \l Q_CHECK_PTR macro,
which will throw a \c std::bad_alloc exception if the application is being
compiled with exception support. If exceptions are disabled, then running
out of memory is undefined behavior.
Note that the operating system may impose further limits on applications
holding a lot of allocated memory, especially large, contiguous blocks.
Such considerations, the configuration of such behavior or any mitigation
are outside the scope of the Qt API.
\sa QVectorIterator, QMutableVectorIterator, QList, QLinkedList
*/

View File

@ -417,7 +417,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
}
QSize outSize(width,height);
if (!scaledSize.isEmpty() && quint32(scaledSize.width()) <= width &&
quint32(scaledSize.height()) <= height && interlace_method == PNG_INTERLACE_NONE) {
quint32(scaledSize.height()) <= height && scaledSize != outSize && interlace_method == PNG_INTERLACE_NONE) {
// Do inline downscaling
outSize = scaledSize;
if (doScaledRead)

View File

@ -3260,9 +3260,12 @@ void QGuiApplication::setPalette(const QPalette &pal)
QGuiApplicationPrivate::app_pal = new QPalette(pal);
else
*QGuiApplicationPrivate::app_pal = pal;
applicationResourceFlags |= ApplicationPaletteExplicitlySet;
QCoreApplication::setAttribute(Qt::AA_SetPalette);
emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal);
if (qGuiApp)
emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal);
}
void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)

View File

@ -452,52 +452,30 @@ QDpi QHighDpiScaling::logicalDpi()
return m_logicalDpi;
}
qreal QHighDpiScaling::factor(const QScreen *screen)
{
// Fast path for when scaling in Qt is not used at all.
if (!m_active)
return qreal(1.0);
// The effective factor for a given screen is the product of the
// screen and global sub-factors
qreal factor = m_factor;
if (screen)
factor *= screenSubfactor(screen->handle());
return factor;
}
qreal QHighDpiScaling::factor(const QPlatformScreen *platformScreen)
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition)
{
if (!m_active)
return qreal(1.0);
return m_factor * screenSubfactor(platformScreen);
return { qreal(1), QPoint() };
const QPlatformScreen *actualScreen = nativePosition ?
platformScreen->screenForPosition(*nativePosition) : platformScreen;
return { m_factor * screenSubfactor(actualScreen), actualScreen->geometry().topLeft() };
}
qreal QHighDpiScaling::factor(const QWindow *window)
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QScreen *screen, QPoint *nativePosition)
{
if (!m_active)
return qreal(1.0);
return factor(window ? window->screen() : QGuiApplication::primaryScreen());
return { qreal(1), QPoint() };
if (!screen)
return { m_factor, QPoint() }; // the global factor
return scaleAndOrigin(screen->handle(), nativePosition);
}
QPoint QHighDpiScaling::origin(const QScreen *screen)
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QWindow *window, QPoint *nativePosition)
{
return screen->geometry().topLeft();
}
QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
{
return platformScreen->geometry().topLeft();
}
QPoint QHighDpiScaling::origin(const QWindow *window)
{
if (window && window->isTopLevel() && window->screen())
return window->screen()->geometry().topLeft();
return QPoint(0, 0);
if (!m_active)
return { qreal(1), QPoint() };
QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
return scaleAndOrigin(screen, nativePosition);
}
#endif //QT_NO_HIGHDPISCALING

View File

@ -78,14 +78,23 @@ public:
static void setScreenFactor(QScreen *window, qreal factor);
static bool isActive() { return m_active; }
static qreal factor(const QWindow *window);
static qreal factor(const QScreen *screen);
static qreal factor(const QPlatformScreen *platformScreen);
static QPoint origin(const QScreen *screen);
static QPoint origin(const QPlatformScreen *platformScreen);
static QPoint origin(const QWindow *window);
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
struct ScaleAndOrigin
{
qreal factor;
QPoint origin;
};
static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition = nullptr);
static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, QPoint *nativePosition = nullptr);
static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, QPoint *nativePosition = nullptr);
template<typename C>
static qreal factor(C *context, QPoint *nativePosition = nullptr) {
return scaleAndOrigin(context, nativePosition).factor;
}
static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
static QPoint mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
static QDpi logicalDpi();
@ -166,16 +175,26 @@ inline QRegion scale(const QRegion &region, qreal scaleFactor, QPoint origin = Q
return scaled;
}
template <typename T>
inline QPoint position(T) { return QPoint(); }
inline QPoint position(QPoint point) { return point; }
inline QPoint position(QPointF point) { return point.toPoint(); }
inline QPoint position(QRect rect) { return rect.center(); }
inline QPoint position(QRectF rect) { return rect.center().toPoint(); }
template <typename T, typename C>
T fromNativePixels(const T &value, const C *context)
{
return scale(value, qreal(1) / QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
QPoint nativePosition = position(value);
QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context, &nativePosition);
return scale(value, qreal(1) / so.factor, so.origin);
}
template <typename T, typename C>
T toNativePixels(const T &value, const C *context)
{
return scale(value, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
return scale(value, so.factor, so.origin);
}
template <typename T, typename C>

View File

@ -309,11 +309,15 @@ void QBasicDrag::updateCursor(Qt::DropAction action)
m_dndHasSetOverrideCursor = true;
} else {
QCursor *cursor = QGuiApplication::overrideCursor();
if (!pixmap.isNull()) {
if (cursor->pixmap().cacheKey() != pixmap.cacheKey())
QGuiApplication::changeOverrideCursor(QCursor(pixmap));
} else if (cursorShape != cursor->shape()) {
QGuiApplication::changeOverrideCursor(QCursor(cursorShape));
if (!cursor) {
QGuiApplication::changeOverrideCursor(pixmap.isNull() ? QCursor(cursorShape) : QCursor(pixmap));
} else {
if (!pixmap.isNull()) {
if (cursor->pixmap().cacheKey() != pixmap.cacheKey())
QGuiApplication::changeOverrideCursor(QCursor(pixmap));
} else if (cursorShape != cursor->shape()) {
QGuiApplication::changeOverrideCursor(QCursor(cursorShape));
}
}
}
#endif

View File

@ -1579,19 +1579,21 @@ void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpN
// dialog is displaying
pauseConnection();
QHttpNetworkReply *reply;
#ifndef QT_NO_SSL
if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY) {
if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
|| connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
#if QT_CONFIG(ssl)
|| connectionType == QHttpNetworkConnection::ConnectionTypeSPDY
#endif
) {
// we choose the reply to emit the proxyAuth signal from somewhat arbitrarily,
// but that does not matter because the signal will ultimately be emitted
// by the QNetworkAccessManager.
Q_ASSERT(chan->spdyRequestsToSend.count() > 0);
reply = chan->spdyRequestsToSend.cbegin().value().second;
} else { // HTTP
#endif // QT_NO_SSL
reply = chan->reply;
#ifndef QT_NO_SSL
}
#endif // QT_NO_SSL
Q_ASSERT(reply);
emit reply->proxyAuthenticationRequired(proxy, auth);

View File

@ -209,6 +209,9 @@ void QHttpNetworkConnectionChannel::init()
void QHttpNetworkConnectionChannel::close()
{
if (state == QHttpNetworkConnectionChannel::ClosingState)
return;
if (!socket)
state = QHttpNetworkConnectionChannel::IdleState;
else if (socket->state() == QAbstractSocket::UnconnectedState)
@ -1125,11 +1128,13 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth)
{
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
|| connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
#ifndef QT_NO_SSL
|| connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY
#endif
) {
connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth);
if (spdyRequestsToSend.count() > 0)
connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth);
} else { // HTTP
// Need to dequeue the request before we can emit the error.
if (!reply)

View File

@ -1611,8 +1611,10 @@ qint64 QSocks5SocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea
QSocks5RevivedDatagram datagram = d->udpData->pendingDatagrams.dequeue();
int copyLen = qMin<int>(maxlen, datagram.data.size());
memcpy(data, datagram.data.constData(), copyLen);
header->senderAddress = datagram.address;
header->senderPort = datagram.port;
if (header) {
header->senderAddress = datagram.address;
header->senderPort = datagram.port;
}
return copyLen;
#else
Q_UNUSED(data)

View File

@ -1573,7 +1573,6 @@ bool QSslSocketBackendPrivate::checkOcspStatus()
// verify the responder's chain (see their commit 4ba9a4265bd).
// Working this around - is too much fuss for ancient versions we
// are dropping quite soon anyway.
const unsigned long verificationFlags = 0;
const int success = q_OCSP_basic_verify(basicResponse, peerChain, store, verificationFlags);
if (success <= 0)

View File

@ -558,6 +558,7 @@ static inline int getBlockPosition(const QSharedPointer<QInputMethodQueryEvent>
void QAndroidInputContext::reset()
{
focusObjectStopComposing();
clear();
m_batchEditNestingLevel = 0;
m_handleMode = Hidden;
@ -792,7 +793,25 @@ void QAndroidInputContext::touchDown(int x, int y)
m_handleMode = ShowCursor;
// The VK will appear in a moment, stop the timer
m_hideCursorHandleTimer.stop();
focusObjectStopComposing();
if (focusObjectIsComposing()) {
const double pixelDensity =
QGuiApplication::focusWindow()
? QHighDpiScaling::factor(QGuiApplication::focusWindow())
: QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen());
const QPointF touchPointLocal =
QGuiApplication::inputMethod()->inputItemTransform().inverted().map(
QPointF(x / pixelDensity, y / pixelDensity));
const int curBlockPos = getBlockPosition(
focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImAbsolutePosition));
const int touchPosition = curBlockPos
+ QInputMethod::queryFocusObject(Qt::ImCursorPosition, touchPointLocal).toInt();
if (touchPosition != m_composingCursor)
focusObjectStopComposing();
}
updateSelectionHandles();
}
}
@ -1200,13 +1219,18 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt();
const int localPos = query->value(Qt::ImCursorPosition).toInt();
bool atWordBoundary = (localPos == 0);
bool atWordBoundary =
localPos == 0
&& (!focusObjectIsComposing() || m_composingCursor == m_composingTextStart);
if (!atWordBoundary) {
QString surroundingText = query->value(Qt::ImSurroundingText).toString();
surroundingText.truncate(localPos);
if (focusObjectIsComposing())
surroundingText += m_composingText.leftRef(m_composingCursor - m_composingTextStart);
// Add a character to see if it is at the end of the sentence or not
QTextBoundaryFinder finder(QTextBoundaryFinder::Sentence, surroundingText + QLatin1Char('A'));
finder.setPosition(localPos);
finder.setPosition(surroundingText.length());
if (finder.isAtBoundary())
atWordBoundary = finder.isAtBoundary();
}

View File

@ -489,6 +489,8 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
Q_FALLTHROUGH();
}
case DialogButtonBoxLayout:
return QVariant(QPlatformDialogHelper::AndroidLayout);
default:
return QPlatformTheme::themeHint(hint);
}

View File

@ -215,6 +215,25 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
connect(qGuiApp, &QGuiApplication::focusWindowChanged,
this, &QCocoaIntegration::focusWindowChanged);
static auto splashScreenHider = QMacKeyValueObserver(NSApp, @"modalWindow", []{
const QWindowList allWindows = QGuiApplication::topLevelWindows();
for (QWindow *window : allWindows) {
if ((window->flags() & Qt::SplashScreen) == Qt::SplashScreen) {
QCocoaWindow *platformWindow = static_cast<QCocoaWindow*>(window->handle());
NSWindow *splashWindow = platformWindow->view().window;
if (!splashWindow)
continue;
if (NSApp.modalWindow) {
NSInteger originalLevel = splashWindow.level;
splashWindow.level = NSNormalWindowLevel;
window->setProperty("_q_levelBeforeModalSession", (qlonglong)originalLevel);
} else if (NSInteger originalLevel = window->property("_q_levelBeforeModalSession").toLongLong()) {
splashWindow.level = originalLevel;
}
}
}
});
}
QCocoaIntegration::~QCocoaIntegration()

View File

@ -189,10 +189,15 @@ static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidge
}
#endif
/* if a floating tool window is active, keep shortcuts on the
* parent working */
if (active_window != tlw && active_window && active_window->windowType() == Qt::Tool && active_window->parentWidget()) {
active_window = active_window->parentWidget()->window();
if (active_window && active_window != tlw) {
/* if a floating tool window is active, keep shortcuts on the parent working.
* and if a popup window is active (f.ex a completer), keep shortcuts on the
* focus proxy working */
if (active_window->windowType() == Qt::Tool && active_window->parentWidget()) {
active_window = active_window->parentWidget()->window();
} else if (active_window->windowType() == Qt::Popup && active_window->focusProxy()) {
active_window = active_window->focusProxy()->window();
}
}
if (active_window != tlw) {

View File

@ -30,6 +30,8 @@
#include <QtTest/QtTest>
#include <qapplication.h>
#include <qtextedit.h>
#include <qlineedit.h>
#include <qcompleter.h>
#include <qpushbutton.h>
#include <qmainwindow.h>
#include <qstatusbar.h>
@ -120,6 +122,7 @@ private slots:
void unicodeCompare();
void context();
void duplicatedShortcutOverride();
void shortcutToFocusProxy();
protected:
static Qt::KeyboardModifiers toButtons( int key );
@ -1279,5 +1282,28 @@ void tst_QShortcut::testElement()
}
}
void tst_QShortcut::shortcutToFocusProxy()
{
QLineEdit le;
QCompleter completer;
QStringListModel *slm = new QStringListModel(QStringList() << "a0" << "a1" << "a2", &completer);
completer.setModel(slm);
completer.setCompletionMode(QCompleter::PopupCompletion);
le.setCompleter(&completer);
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::Key_S), &le);
QObject::connect(shortcut, &QShortcut::activated, &le, &QLineEdit::clear);
le.setFocus();
le.show();
QVERIFY(QTest::qWaitForWindowActive(&le));
QCOMPARE(QApplication::focusWidget(), &le);
QTest::keyEvent(QTest::Press, QApplication::focusWidget(), Qt::Key_A);
QCOMPARE(le.text(), QString::fromLocal8Bit("a"));
QTest::keyEvent(QTest::Press, QApplication::focusWidget(), Qt::Key_Alt);
QTest::keyEvent(QTest::Press, QApplication::focusWidget(), Qt::Key_S, Qt::AltModifier);
QCOMPARE(le.text(), QString());
}
QTEST_MAIN(tst_QShortcut)
#include "tst_qshortcut.moc"

View File

@ -39,19 +39,19 @@ class DebugProxyStyle : public QProxyStyle {
public:
explicit DebugProxyStyle(QStyle *style);
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const;
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const;
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const;
QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const;
QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const;
int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const;
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const;
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override;
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override;
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override;
void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const override;
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override;
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override;
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override;
QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const override;
QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const override;
int styleHint(StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override;
int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override;
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = nullptr) const override;
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override;
};
} // namespace QtDiag

View File

@ -197,7 +197,7 @@ static void formatApplicationState(QDebug debug)
static void formatMouseState(QObject *o, QDebug debug)
{
if (o->isWidgetType()) {
const QWidget *w = static_cast<const QWidget *>(o);
auto w = static_cast<const QWidget *>(o);
if (QWidget::mouseGrabber() == w)
debug << " [grabbed]";
if (w->hasMouseTracking())

View File

@ -68,10 +68,10 @@ public:
};
Q_DECLARE_FLAGS(ObjectTypes, ObjectType)
explicit EventFilter(EventCategories eventCategories, QObject *p = 0);
explicit EventFilter(QObject *p = 0);
explicit EventFilter(EventCategories eventCategories, QObject *p = nullptr);
explicit EventFilter(QObject *p = nullptr);
bool eventFilter(QObject *, QEvent *);
bool eventFilter(QObject *, QEvent *) override;
ObjectTypes objectTypes() const { return m_objectTypes; }
void setObjectTypes(ObjectTypes objectTypes) { m_objectTypes = objectTypes; }

View File

@ -40,7 +40,7 @@
#include <iostream>
LogWidget *LogWidget::m_instance = 0;
LogWidget *LogWidget::m_instance = nullptr;
bool LogWidget::m_lineNumberingEnabled = true;
bool LogWidget::m_showMessageType = true;
int LogWidget::m_indent = 0;
@ -54,7 +54,7 @@ LogWidget::LogWidget(QWidget *parent)
LogWidget::~LogWidget()
{
LogWidget::m_instance = 0;
LogWidget::m_instance = nullptr;
}
QString LogWidget::startupMessage()

View File

@ -46,7 +46,7 @@ class LogWidget : public QPlainTextEdit
{
Q_OBJECT
public:
explicit LogWidget(QWidget *parent = 0);
explicit LogWidget(QWidget *parent = nullptr);
~LogWidget();
static LogWidget *instance() { return m_instance; }

View File

@ -59,8 +59,8 @@ static const char *qtWidgetClasses[] = {
static bool isQtWidget(const char *className)
{
for (size_t i = 0, count = sizeof(qtWidgetClasses) / sizeof(qtWidgetClasses[0]); i < count; ++i) {
if (!qstrcmp(className, qtWidgetClasses[i]))
for (auto qtWidgetClass : qtWidgetClasses) {
if (qstrcmp(className, qtWidgetClass) == 0)
return true;
}
return false;

View File

@ -35,7 +35,7 @@ QT_FORWARD_DECLARE_CLASS(QWidget)
namespace QtDiag {
void dumpAllWidgets(FormatWindowOptions options = 0, const QWidget *root = 0);
void dumpAllWidgets(FormatWindowOptions options = {}, const QWidget *root = nullptr);
} // namespace QtDiag

View File

@ -73,7 +73,7 @@ if ((type & typeConstant) == typeConstant) \
if (flags & flagConstant) \
s << ' ' << #flagConstant;
void formatWindowFlags(QTextStream &str, const Qt::WindowFlags flags)
void formatWindowFlags(QTextStream &str, Qt::WindowFlags flags)
{
str << showbase << hex << unsigned(flags) << dec << noshowbase;
const Qt::WindowFlags windowType = flags & Qt::WindowType_Mask;
@ -158,7 +158,7 @@ void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions option
}
static void dumpWindowRecursion(QTextStream &str, const QWindow *w,
FormatWindowOptions options = 0, int depth = 0)
FormatWindowOptions options = {}, int depth = 0)
{
indentStream(str, 2 * depth);
formatWindow(str, w, options);

View File

@ -49,10 +49,10 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(FormatWindowOptions)
void indentStream(QTextStream &s, int indent);
void formatObject(QTextStream &str, const QObject *o);
void formatRect(QTextStream &str, const QRect &geom);
void formatWindowFlags(QTextStream &str, const Qt::WindowFlags flags);
void formatWindowFlags(QTextStream &str, Qt::WindowFlags flags);
void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions options = 0);
void dumpAllWindows(FormatWindowOptions options = 0);
void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions options = {});
void dumpAllWindows(FormatWindowOptions options = {});
} // namespace QtDiag

View File

@ -381,7 +381,7 @@ static const EnumLookup *enumLookup(int v, const EnumLookup *array, size_t size)
if (p->value == v)
return p;
}
return 0;
return nullptr;
}
static const char *enumName(int v, const EnumLookup *array, size_t size)
@ -394,15 +394,12 @@ static const char *enumName(int v, const EnumLookup *array, size_t size)
// that change will be output.
struct FormattingContext
{
FormattingContext() : category(-1), direction(-1), joiningType(-1)
, decompositionTag(-1), script(-1), unicodeVersion(-1) {}
int category;
int direction;
int joiningType;
int decompositionTag;
int script;
int unicodeVersion;
int category = -1;
int direction = -1;
int joiningType = -1;
int decompositionTag = -1;
int script = -1;
int unicodeVersion = -1;
};
static void formatCharacter(QTextStream &str, const QChar &qc, FormattingContext &context)
@ -478,8 +475,8 @@ QString dumpTextAsCode(const QString &text)
QString result;
QTextStream str(&result);
str << " QString result;\n" << hex << showbase;
for (int i = 0; i < text.size(); ++i)
str << " result += QChar(" << text.at(i).unicode() << ");\n";
for (QChar c : text)
str << " result += QChar(" << c.unicode() << ");\n";
str << '\n';
return result;
}