Merge remote-tracking branch 'origin/5.12' into dev

Conflicts:
	src/widgets/styles/qstylesheetstyle.cpp

Change-Id: I3a503b44ae413fbc0a90f4af70b8f84daffd86ad
This commit is contained in:
Liang Qi 2018-10-08 10:56:25 +02:00
commit 7344987c20
70 changed files with 579 additions and 236 deletions

View File

@ -7,7 +7,7 @@ QMAKE_MAC_SDK = macosx
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
QMAKE_APPLE_DEVICE_ARCHS = x86_64
QT_MAC_SDK_VERSION_TESTED_WITH = 10.13
QT_MAC_SDK_VERSION_TESTED_WITH = 10.14
device.sdk = macosx
device.target = device

View File

@ -18,18 +18,16 @@ contains(TEMPLATE, .*app) {
!isEmpty($$list($$(QT_MAC_SDK_NO_VERSION_CHECK))): \
CONFIG += sdk_no_version_check
!sdk_no_version_check:!versionAtMost(QMAKE_MAC_SDK_VERSION, $$QT_MAC_SDK_VERSION_TESTED_WITH) {
QMAKE_MAC_SDK_MAJOR_MINOR_VERSION = $$replace(QMAKE_MAC_SDK_VERSION, "(\d+)(\.\d+)(\.\d+)?", \1\2)
!sdk_no_version_check:!versionAtMost(QMAKE_MAC_SDK_MAJOR_MINOR_VERSION, $$QT_MAC_SDK_VERSION_TESTED_WITH) {
warning("Qt has only been tested with version $$QT_MAC_SDK_VERSION_TESTED_WITH"\
"of the platform SDK, you're using $${QMAKE_MAC_SDK_VERSION}.")
"of the platform SDK, you're using $${QMAKE_MAC_SDK_MAJOR_MINOR_VERSION}.")
warning("This is an unsupported configuration. You may experience build issues," \
"and by using")
warning("the $$QMAKE_MAC_SDK_VERSION SDK you are opting in to new features" \
"that Qt has not been prepared for.")
isEqual(QMAKE_MAC_SDK_VERSION, 10.14): \
warning("E.g., 10.14 enables dark mode and layer-backed views," \
"which Qt $${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION} does not support.")
warning("Please downgrade the SDK you use to build your app to version" \
"$$QT_MAC_SDK_VERSION_TESTED_WITH, or configure")
warning("with CONFIG+=sdk_no_version_check when running qmake" \

View File

@ -5,7 +5,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.android.tools.build:gradle:3.2.0'
}
}

View File

@ -353,7 +353,10 @@ while (i.hasNext()) {
{
//! [31]
QString wildcard = QRegularExpression::wildcardToRegularExpression("*.jpeg");
// wilcard == ".*\.jpeg"
// Will match files with names like:
// foo.jpeg
// f_o_o.jpeg
// föö.jpeg
//! [31]
}

View File

@ -2731,6 +2731,7 @@ void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
QRegExp rx(pattern);
rx.setCaseSensitivity(d->filter_data.caseSensitivity());
d->filter_data.setRegExp(rx);
d->filter_changed();
}

View File

@ -88,11 +88,9 @@ public:
QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection) const override;
QRegExp filterRegExp() const;
void setFilterRegExp(const QRegExp &regExp);
#if QT_CONFIG(regularexpression)
QRegularExpression filterRegularExpression() const;
void setFilterRegularExpression(const QRegularExpression &regularExpression);
#endif
int filterKeyColumn() const;
@ -124,8 +122,10 @@ public:
public Q_SLOTS:
void setFilterRegExp(const QString &pattern);
void setFilterRegExp(const QRegExp &regExp);
#if QT_CONFIG(regularexpression)
void setFilterRegularExpression(const QString &pattern);
void setFilterRegularExpression(const QRegularExpression &regularExpression);
#endif
void setFilterWildcard(const QString &pattern);
void setFilterFixedString(const QString &pattern);

View File

@ -482,6 +482,10 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
qFatal("FATAL: The application binary appears to be running setuid, this is a security hole.");
# endif // Q_OS_UNIX
#ifdef Q_OS_WINRT
QThreadData::setMainThread();
#endif
QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread!
if (cur != theMainThread)
qWarning("WARNING: QApplication was not created in the main() thread.");

View File

@ -243,6 +243,9 @@ public:
~QThreadData();
static Q_AUTOTEST_EXPORT QThreadData *current(bool createIfNecessary = true);
#ifdef Q_OS_WINRT
static void setMainThread();
#endif
static void clearCurrentThreadData();
static QThreadData *get2(QThread *thread)
{ Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; }

View File

@ -140,11 +140,15 @@ QThreadData *QThreadData::current(bool createIfNecessary)
threadData->isAdopted = true;
threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
#ifndef Q_OS_WINRT
if (!QCoreApplicationPrivate::theMainThread) {
QCoreApplicationPrivate::theMainThread = threadData->thread.load();
// TODO: is there a way to reflect the branch's behavior using
// WinRT API?
} else {
#else
// for winrt the main thread is set explicitly in QCoreApplication's constructor as the
// native main thread (Xaml thread) is not Qt's main thread.
{
#endif
HANDLE realHandle = INVALID_HANDLE_VALUE;
DuplicateHandle(GetCurrentProcess(),
GetCurrentThread(),
@ -159,6 +163,33 @@ QThreadData *QThreadData::current(bool createIfNecessary)
return threadData;
}
#ifdef Q_OS_WINRT
void QThreadData::setMainThread()
{
Q_ASSERT(!QCoreApplicationPrivate::theMainThread);
qt_create_tls();
QThreadData *threadData = reinterpret_cast<QThreadData *>(TlsGetValue(qt_current_thread_data_tls_index));
if (!threadData) {
threadData = new QThreadData;
// This needs to be called prior to new AdoptedThread() to
// avoid recursion.
TlsSetValue(qt_current_thread_data_tls_index, threadData);
QT_TRY {
threadData->thread = new QAdoptedThread(threadData);
} QT_CATCH(...) {
TlsSetValue(qt_current_thread_data_tls_index, 0);
threadData->deref();
threadData = 0;
QT_RETHROW;
}
threadData->deref();
threadData->isAdopted = true;
threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
}
QCoreApplicationPrivate::theMainThread = threadData->thread.load();
}
#endif
void QAdoptedThread::init()
{
d_func()->handle = GetCurrentThread();

View File

@ -55,6 +55,11 @@
#include <QtGui/qrgb.h>
#include <QtGui/qrgba64.h>
#if defined(__SSE2__)
#include <emmintrin.h>
#elif defined(__ARM_NEON__) || defined(__ARM_NEON)
#include <arm_neon.h>
#endif
QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QColorProfile
@ -67,82 +72,165 @@ public:
QRgba64 toLinear64(QRgb rgb32) const
{
ushort r = m_toLinear[qRed(rgb32) << 4];
ushort g = m_toLinear[qGreen(rgb32) << 4];
ushort b = m_toLinear[qBlue(rgb32) << 4];
#if defined(__SSE2__)
__m128i v = _mm_cvtsi32_si128(rgb32);
v = _mm_unpacklo_epi8(v, _mm_setzero_si128());
const __m128i vidx = _mm_slli_epi16(v, 4);
const int ridx = _mm_extract_epi16(vidx, 2);
const int gidx = _mm_extract_epi16(vidx, 1);
const int bidx = _mm_extract_epi16(vidx, 0);
v = _mm_slli_epi16(v, 8); // a * 256
v = _mm_insert_epi16(v, m_toLinear[ridx], 0);
v = _mm_insert_epi16(v, m_toLinear[gidx], 1);
v = _mm_insert_epi16(v, m_toLinear[bidx], 2);
v = _mm_add_epi16(v, _mm_srli_epi16(v, 8));
QRgba64 rgba64;
_mm_storel_epi64(reinterpret_cast<__m128i *>(&rgba64), v);
return rgba64;
#elif (defined(__ARM_NEON__) || defined(__ARM_NEON)) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN
uint8x8_t v8 = vreinterpret_u8_u32(vmov_n_u32(rgb32));
uint16x4_t v16 = vget_low_u16(vmovl_u8(v8));
const uint16x4_t vidx = vshl_n_u16(v16, 4);
const int ridx = vget_lane_u16(vidx, 2);
const int gidx = vget_lane_u16(vidx, 1);
const int bidx = vget_lane_u16(vidx, 0);
v16 = vshl_n_u16(v16, 8); // a * 256
v16 = vset_lane_u16(m_toLinear[ridx], v16, 0);
v16 = vset_lane_u16(m_toLinear[gidx], v16, 1);
v16 = vset_lane_u16(m_toLinear[bidx], v16, 2);
v16 = vadd_u16(v16, vshr_n_u16(v16, 8));
return QRgba64::fromRgba64(vget_lane_u64(vreinterpret_u64_u16(v16), 0));
#else
uint r = m_toLinear[qRed(rgb32) << 4];
uint g = m_toLinear[qGreen(rgb32) << 4];
uint b = m_toLinear[qBlue(rgb32) << 4];
r = r + (r >> 8);
g = g + (g >> 8);
b = b + (b >> 8);
return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257);
#endif
}
QRgb toLinear(QRgb rgb32) const
{
uchar r = (m_toLinear[qRed(rgb32) << 4] + 0x80) >> 8;
uchar g = (m_toLinear[qGreen(rgb32) << 4] + 0x80) >> 8;
uchar b = (m_toLinear[qBlue(rgb32) << 4] + 0x80) >> 8;
return qRgba(r, g, b, qAlpha(rgb32));
return convertWithTable(rgb32, m_toLinear);
}
QRgba64 toLinear(QRgba64 rgb64) const
{
ushort r = rgb64.red();
ushort g = rgb64.green();
ushort b = rgb64.blue();
r = r - (r >> 8);
g = g - (g >> 8);
b = b - (b >> 8);
r = m_toLinear[r >> 4];
g = m_toLinear[g >> 4];
b = m_toLinear[b >> 4];
r = r + (r >> 8);
g = g + (g >> 8);
b = b + (b >> 8);
return QRgba64::fromRgba64(r, g, b, rgb64.alpha());
return convertWithTable(rgb64, m_toLinear);
}
QRgb fromLinear64(QRgba64 rgb64) const
{
ushort r = rgb64.red();
ushort g = rgb64.green();
ushort b = rgb64.blue();
#if defined(__SSE2__)
__m128i v = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(&rgb64));
v = _mm_sub_epi16(v, _mm_srli_epi16(v, 8));
const __m128i vidx = _mm_srli_epi16(v, 4);
const int ridx = _mm_extract_epi16(vidx, 0);
const int gidx = _mm_extract_epi16(vidx, 1);
const int bidx = _mm_extract_epi16(vidx, 2);
v = _mm_insert_epi16(v, m_fromLinear[ridx], 2);
v = _mm_insert_epi16(v, m_fromLinear[gidx], 1);
v = _mm_insert_epi16(v, m_fromLinear[bidx], 0);
v = _mm_add_epi16(v, _mm_set1_epi16(0x80));
v = _mm_srli_epi16(v, 8);
v = _mm_packus_epi16(v, v);
return _mm_cvtsi128_si32(v);
#elif (defined(__ARM_NEON__) || defined(__ARM_NEON)) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN
uint16x4_t v = vreinterpret_u16_u64(vmov_n_u64(rgb64));
v = vsub_u16(v, vshr_n_u16(v, 8));
const uint16x4_t vidx = vshr_n_u16(v, 4);
const int ridx = vget_lane_u16(vidx, 0);
const int gidx = vget_lane_u16(vidx, 1);
const int bidx = vget_lane_u16(vidx, 2);
v = vset_lane_u16(m_fromLinear[ridx], v, 2);
v = vset_lane_u16(m_fromLinear[gidx], v, 1);
v = vset_lane_u16(m_fromLinear[bidx], v, 0);
uint8x8_t v8 = vrshrn_n_u16(vcombine_u16(v, v), 8);
return vget_lane_u32(vreinterpret_u32_u8(v8), 0);
#else
uint a = rgb64.alpha();
uint r = rgb64.red();
uint g = rgb64.green();
uint b = rgb64.blue();
a = a - (a >> 8);
r = r - (r >> 8);
g = g - (g >> 8);
b = b - (b >> 8);
a = (a + 0x80) >> 8;
r = (m_fromLinear[r >> 4] + 0x80) >> 8;
g = (m_fromLinear[g >> 4] + 0x80) >> 8;
b = (m_fromLinear[b >> 4] + 0x80) >> 8;
return qRgba(r, g, b, rgb64.alpha8());
return (a << 24) | (r << 16) | (g << 8) | b;
#endif
}
QRgb fromLinear(QRgb rgb32) const
{
uchar r = (m_fromLinear[qRed(rgb32) << 4] + 0x80) >> 8;
uchar g = (m_fromLinear[qGreen(rgb32) << 4] + 0x80) >> 8;
uchar b = (m_fromLinear[qBlue(rgb32) << 4] + 0x80) >> 8;
return qRgba(r, g, b, qAlpha(rgb32));
return convertWithTable(rgb32, m_fromLinear);
}
QRgba64 fromLinear(QRgba64 rgb64) const
{
return convertWithTable(rgb64, m_fromLinear);
}
private:
QColorProfile() { }
Q_ALWAYS_INLINE static QRgb convertWithTable(QRgb rgb32, const ushort *table)
{
const int r = (table[qRed(rgb32) << 4] + 0x80) >> 8;
const int g = (table[qGreen(rgb32) << 4] + 0x80) >> 8;
const int b = (table[qBlue(rgb32) << 4] + 0x80) >> 8;
return (rgb32 & 0xff000000) | (r << 16) | (g << 8) | b;
}
Q_ALWAYS_INLINE static QRgba64 convertWithTable(QRgba64 rgb64, const ushort *table)
{
#if defined(__SSE2__)
__m128i v = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(&rgb64));
v = _mm_sub_epi16(v, _mm_srli_epi16(v, 8));
const __m128i vidx = _mm_srli_epi16(v, 4);
const int ridx = _mm_extract_epi16(vidx, 2);
const int gidx = _mm_extract_epi16(vidx, 1);
const int bidx = _mm_extract_epi16(vidx, 0);
v = _mm_insert_epi16(v, table[ridx], 2);
v = _mm_insert_epi16(v, table[gidx], 1);
v = _mm_insert_epi16(v, table[bidx], 0);
v = _mm_add_epi16(v, _mm_srli_epi16(v, 8));
QRgba64 rgba64;
_mm_storel_epi64(reinterpret_cast<__m128i *>(&rgba64), v);
return rgba64;
#elif (defined(__ARM_NEON__) || defined(__ARM_NEON)) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN
uint16x4_t v = vreinterpret_u16_u64(vmov_n_u64(rgb64));
v = vsub_u16(v, vshr_n_u16(v, 8));
const uint16x4_t vidx = vshr_n_u16(v, 4);
const int ridx = vget_lane_u16(vidx, 2);
const int gidx = vget_lane_u16(vidx, 1);
const int bidx = vget_lane_u16(vidx, 0);
v = vset_lane_u16(table[ridx], v, 2);
v = vset_lane_u16(table[gidx], v, 1);
v = vset_lane_u16(table[bidx], v, 0);
v = vadd_u16(v, vshr_n_u16(v, 8));
return QRgba64::fromRgba64(vget_lane_u64(vreinterpret_u64_u16(v), 0));
#else
ushort r = rgb64.red();
ushort g = rgb64.green();
ushort b = rgb64.blue();
r = r - (r >> 8);
g = g - (g >> 8);
b = b - (b >> 8);
r = m_fromLinear[r >> 4];
g = m_fromLinear[g >> 4];
b = m_fromLinear[b >> 4];
r = table[r >> 4];
g = table[g >> 4];
b = table[b >> 4];
r = r + (r >> 8);
g = g + (g >> 8);
b = b + (b >> 8);
return QRgba64::fromRgba64(r, g, b, rgb64.alpha());
#endif
}
private:
QColorProfile() { }
// We translate to 0-65280 (255*256) instead to 0-65535 to make simple
// shifting an accurate conversion.
// We translate from 0-4080 (255*16) for the same speed up, and to keep

View File

@ -108,8 +108,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
[mFontPanel setRestorable:NO];
[mFontPanel setDelegate:self];
[NSFontManager sharedFontManager].target = self; // Action is changeFont:
[mFontPanel retain];
}
return self;
@ -119,7 +117,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
{
[mStolenContentView release];
[mFontPanel setDelegate:nil];
[NSFontManager sharedFontManager].target = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
@ -224,6 +221,13 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
return (mResultCode == NSModalResponseOK);
}
// Future proofing in case _NSTargetForSendAction checks this
// property before sending us the changeFont: message.
- (BOOL)worksWhenModal
{
return YES;
}
- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
return (mResultCode == NSModalResponseOK) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;

View File

@ -41,6 +41,7 @@
#define QCOCOAGLCONTEXT_H
#include <QtCore/QPointer>
#include <QtCore/private/qcore_mac_p.h>
#include <qpa/qplatformopenglcontext.h>
#include <QtGui/QOpenGLContext>
#include <QtGui/QWindow>
@ -79,6 +80,8 @@ private:
NSOpenGLContext *m_shareContext = nil;
QSurfaceFormat m_format;
bool m_didCheckForSoftwareContext = false;
QVarLengthArray<QMacScopedObserver, 3> m_updateObservers;
QAtomicInt m_needsUpdate = false;
};
QT_END_NAMESPACE

View File

@ -41,7 +41,6 @@
#include "qcocoawindow.h"
#include "qcocoahelpers.h"
#include <qdebug.h>
#include <QtCore/private/qcore_mac_p.h>
#include <QtPlatformHeaders/qcocoanativecontext.h>
#include <dlfcn.h>
@ -351,7 +350,8 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
}
}
update();
if (m_needsUpdate.fetchAndStoreRelaxed(false))
update();
}
return true;
@ -383,13 +383,44 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
if (view == m_context.view)
return true;
// Setting the drawable may happen on a separate thread as a result of
// a call to makeCurrent, so we need to set up the observers before we
// associate the view with the context. That way we will guarantee that
// as long as the view is the drawable of the context we will know about
// any updates to the view that require surface invalidation.
auto updateCallback = [this, view]() {
Q_ASSERT(QThread::currentThread() == qApp->thread());
if (m_context.view != view)
return;
m_needsUpdate = true;
};
m_updateObservers.clear();
if (view.layer) {
m_updateObservers.append(QMacScopedObserver(view, NSViewFrameDidChangeNotification, updateCallback));
m_updateObservers.append(QMacScopedObserver(view.window, NSWindowDidChangeScreenNotification, updateCallback));
} else {
m_updateObservers.append(QMacScopedObserver(view, NSViewGlobalFrameDidChangeNotification, updateCallback));
}
m_updateObservers.append(QMacScopedObserver([NSApplication sharedApplication],
NSApplicationDidChangeScreenParametersNotification, updateCallback));
// If any of the observers fire at this point it's fine. We check the
// view association (atomically) in the update callback, and skip the
// update if we haven't associated yet. Setting the drawable below will
// have the same effect as an update.
// Now we are ready to associate the view with the context
if ((m_context.view = view) != view) {
qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context;
m_updateObservers.clear();
return false;
}
qCInfo(lcQpaOpenGLContext) << "Set drawable for" << m_context << "to" << m_context.view;
return true;
}

View File

@ -89,15 +89,12 @@ public:
void clearMappings();
private:
QCFType<TISInputSourceRef> currentInputSource;
QCFType<TISInputSourceRef> currentInputSource = nullptr;
enum { NullMode, UnicodeMode, OtherMode } keyboard_mode;
union {
const UCKeyboardLayout *unicode;
void *other;
} keyboard_layout_format;
KeyboardLayoutKind keyboard_kind;
UInt32 keyboard_dead;
enum { NullMode, UnicodeMode, OtherMode } keyboard_mode = NullMode;
const UCKeyboardLayout *keyboard_layout_format = nullptr;
KeyboardLayoutKind keyboard_kind = kKLKCHRuchrKind;
UInt32 keyboard_dead = 0;
KeyboardLayoutItem *keyLayout[256];
};

View File

@ -341,8 +341,6 @@ static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
QCocoaKeyMapper::QCocoaKeyMapper()
{
memset(keyLayout, 0, sizeof(keyLayout));
keyboard_layout_format.unicode = 0;
currentInputSource = 0;
}
QCocoaKeyMapper::~QCocoaKeyMapper()
@ -371,12 +369,19 @@ bool QCocoaKeyMapper::updateKeyboard()
keyboard_kind = LMGetKbdType();
if (uchrData) {
keyboard_layout_format.unicode = uchrData;
keyboard_layout_format = uchrData;
keyboard_mode = UnicodeMode;
} else {
keyboard_layout_format = nullptr;
keyboard_mode = NullMode;
}
currentInputSource = source;
keyboard_dead = 0;
const auto newMode = keyboard_mode;
deleteLayouts();
keyboard_mode = newMode;
return true;
}
@ -399,10 +404,8 @@ void QCocoaKeyMapper::clearMappings()
void QCocoaKeyMapper::updateKeyMap(unsigned short macVirtualKey, QChar unicodeKey)
{
if (updateKeyboard()) {
// ### Qt 4 did this:
// QKeyMapper::changeKeyboard();
}
updateKeyboard();
if (keyLayout[macVirtualKey])
return;
@ -414,7 +417,7 @@ void QCocoaKeyMapper::updateKeyMap(unsigned short macVirtualKey, QChar unicodeKe
keyLayout[macVirtualKey]->qtKey[i] = 0;
const UInt32 keyModifier = ((qt_mac_get_mac_modifiers(ModsTbl[i]) >> 8) & 0xFF);
OSStatus err = UCKeyTranslate(keyboard_layout_format.unicode, macVirtualKey, kUCKeyActionDown, keyModifier,
OSStatus err = UCKeyTranslate(keyboard_layout_format, macVirtualKey, kUCKeyActionDown, keyModifier,
keyboard_kind, 0, &keyboard_dead, buffer_size, &out_buffer_size, buffer);
if (err == noErr && out_buffer_size) {
const QChar unicode(buffer[0]);

View File

@ -6,7 +6,6 @@ INCLUDEPATH += $$PWD/../../api
CONFIG += egl
LIBS += -lbcm_host
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
# Avoid X11 header collision, use generic EGL native types
DEFINES += QT_EGL_NO_X11

View File

@ -13,7 +13,6 @@ DEFINES += QT_EGL_NO_X11
QMAKE_USE += gbm drm
CONFIG += egl
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfskmsgbmmain.cpp \
$$PWD/qeglfskmsgbmintegration.cpp \

View File

@ -9,7 +9,6 @@ DEFINES += QT_EGL_NO_X11
QMAKE_USE += drm
CONFIG += egl
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfskmsegldevicemain.cpp \
$$PWD/qeglfskmsegldeviceintegration.cpp \

View File

@ -11,7 +11,6 @@ DEFINES += QT_EGL_NO_X11
QMAKE_USE += drm
CONFIG += egl
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfskmsintegration.cpp \
$$PWD/qeglfskmsdevice.cpp \

View File

@ -13,7 +13,6 @@ DEFINES += QT_EGL_NO_X11
QMAKE_USE += gbm drm v4l2
CONFIG += egl
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfskmsvsp2main.cpp \
$$PWD/qeglfskmsvsp2integration.cpp \

View File

@ -7,7 +7,6 @@ DEFINES += QT_EGL_NO_X11
INCLUDEPATH += $$PWD/../../api
CONFIG += egl
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfsmalimain.cpp \
$$PWD/qeglfsmaliintegration.cpp

View File

@ -5,7 +5,6 @@ QT += core-private gui-private eglfsdeviceintegration-private
INCLUDEPATH += $$PWD/../../api
CONFIG += egl
DEFINES += LINUX=1 EGL_API_FB=1
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfsrcarmain.cpp \
$$PWD/qeglfsrcarintegration.cpp

View File

@ -5,7 +5,6 @@ QT += core-private gui-private eglfsdeviceintegration-private
INCLUDEPATH += $$PWD/../../api
CONFIG += egl
DEFINES += LINUX=1 EGL_API_FB=1
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfsvivmain.cpp \
$$PWD/qeglfsvivintegration.cpp

View File

@ -5,7 +5,6 @@ QT += core-private gui-private eglfsdeviceintegration-private
INCLUDEPATH += $$PWD/../../api
CONFIG += egl
DEFINES += LINUX=1 EGL_API_FB=1
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfsvivwlmain.cpp \
$$PWD/qeglfsvivwlintegration.cpp

View File

@ -9,7 +9,6 @@ INCLUDEPATH += $$PWD/../../api
CONFIG += egl
QMAKE_USE += xcb_xlib
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfsx11main.cpp \
$$PWD/qeglfsx11integration.cpp

View File

@ -27,8 +27,6 @@ DEFINES += QT_BUILD_EGL_DEVICE_LIB
include($$PWD/api/api.pri)
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
!isEmpty(EGLFS_PLATFORM_HOOKS_SOURCES) {
HEADERS += $$EGLFS_PLATFORM_HOOKS_HEADERS
SOURCES += $$EGLFS_PLATFORM_HOOKS_SOURCES

View File

@ -39,15 +39,27 @@
#include <QtCore/qobject.h>
#include <QtCore/qdeadlinetimer.h>
#include <emscripten/bind.h>
#include <iostream>
QT_BEGIN_NAMESPACE
using namespace emscripten;
// macOS CTRL <-> META switching. We most likely want to enable
// the existing switching code in QtGui, but for now do it here.
static bool g_usePlatformMacCtrlMetaSwitching = false;
bool g_useNaturalScrolling = false;
void setNaturalScrolling(bool use) {
g_useNaturalScrolling = use;
}
EMSCRIPTEN_BINDINGS(mouse_module) {
function("setNaturalScrolling", &setNaturalScrolling);
}
QWasmEventTranslator::QWasmEventTranslator(QObject *parent)
: QObject(parent)
, draggedWindow(nullptr)
@ -84,6 +96,20 @@ QWasmEventTranslator::QWasmEventTranslator(QObject *parent)
Platform(EM_ASM_INT("if (navigator.platform.includes(\"Mac\")) return 1; return 0;"));
g_usePlatformMacCtrlMetaSwitching = (platform == MacOSPlatform);
if (platform == MacOSPlatform) {
g_useNaturalScrolling = true; //make this default on macOS
EM_ASM(
if (window.safari !== undefined) {//this only works on safari
Module["canvas"].addEventListener('wheel', mouseWheelEvent);
function mouseWheelEvent(e) {
if (event.webkitDirectionInvertedFromDevice) {
Module.setNaturalScrolling(event.webkitDirectionInvertedFromDevice);
}
}
}
);
}
}
template <typename Event>
@ -449,6 +475,9 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
break;
};
if (g_useNaturalScrolling) //macOS platform has document oriented scrolling
scrollFactor = -scrollFactor;
Qt::KeyboardModifiers modifiers = translateMouseEventModifier(&mouseEvent);
auto timestamp = mouseEvent.timestamp;
QPoint globalPoint(mouseEvent.canvasX, mouseEvent.canvasY);

View File

@ -61,6 +61,8 @@
#include <QtCore/qloggingcategory.h>
#include <QtCore/qoperatingsystemversion.h>
#include <algorithm>
#include <windowsx.h>
QT_BEGIN_NAMESPACE
@ -184,41 +186,65 @@ static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeTyp
{POINTER_CHANGE_FIFTHBUTTON_UP, Qt::XButton2},
};
static const QHash<UINT, QEvent::Type> eventMapping {
{WM_POINTERUPDATE, QEvent::MouseMove},
{WM_POINTERDOWN, QEvent::MouseButtonPress},
{WM_POINTERUP, QEvent::MouseButtonRelease},
{WM_NCPOINTERUPDATE, QEvent::NonClientAreaMouseMove},
{WM_NCPOINTERDOWN, QEvent::NonClientAreaMouseButtonPress},
{WM_NCPOINTERUP, QEvent::NonClientAreaMouseButtonRelease},
{WM_POINTERWHEEL, QEvent::Wheel},
{WM_POINTERHWHEEL, QEvent::Wheel},
static const POINTER_BUTTON_CHANGE_TYPE downChanges[] = {
POINTER_CHANGE_FIRSTBUTTON_DOWN,
POINTER_CHANGE_SECONDBUTTON_DOWN,
POINTER_CHANGE_THIRDBUTTON_DOWN,
POINTER_CHANGE_FOURTHBUTTON_DOWN,
POINTER_CHANGE_FIFTHBUTTON_DOWN,
};
static const POINTER_BUTTON_CHANGE_TYPE upChanges[] = {
POINTER_CHANGE_FIRSTBUTTON_UP,
POINTER_CHANGE_SECONDBUTTON_UP,
POINTER_CHANGE_THIRDBUTTON_UP,
POINTER_CHANGE_FOURTHBUTTON_UP,
POINTER_CHANGE_FIFTHBUTTON_UP,
};
if (!eventType || !mouseButton)
return;
if (message == WM_POINTERDOWN || message == WM_POINTERUP || message == WM_NCPOINTERDOWN || message == WM_NCPOINTERUP)
*mouseButton = buttonMapping.value(changeType, Qt::NoButton);
else
*mouseButton = Qt::NoButton;
const bool nonClient = message == WM_NCPOINTERUPDATE ||
message == WM_NCPOINTERDOWN ||
message == WM_NCPOINTERUP;
*eventType = eventMapping.value(message, QEvent::None);
if (std::find(std::begin(downChanges),
std::end(downChanges), changeType) < std::end(downChanges)) {
*eventType = nonClient ? QEvent::NonClientAreaMouseButtonPress :
QEvent::MouseButtonPress;
} else if (std::find(std::begin(upChanges),
std::end(upChanges), changeType) < std::end(upChanges)) {
*eventType = nonClient ? QEvent::NonClientAreaMouseButtonRelease :
QEvent::MouseButtonRelease;
} else if (message == WM_POINTERWHEEL || message == WM_POINTERHWHEEL) {
*eventType = QEvent::Wheel;
} else {
*eventType = nonClient ? QEvent::NonClientAreaMouseMove :
QEvent::MouseMove;
}
*mouseButton = buttonMapping.value(changeType, Qt::NoButton);
// Pointer messages lack a double click indicator. Check if this is the case here.
if (message == WM_POINTERDOWN) {
if (*eventType == QEvent::MouseButtonPress ||
*eventType == QEvent::NonClientAreaMouseButtonPress) {
static LONG lastTime = 0;
static Qt::MouseButton lastButton = Qt::NoButton;
static QEvent::Type lastEvent = QEvent::None;
static QPoint lastPos;
LONG messageTime = GetMessageTime();
if (*mouseButton == lastButton
&& *eventType == lastEvent
&& messageTime - lastTime < (LONG)GetDoubleClickTime()
&& qAbs(globalPos.x() - lastPos.x()) < GetSystemMetrics(SM_CXDOUBLECLK)
&& qAbs(globalPos.y() - lastPos.y()) < GetSystemMetrics(SM_CYDOUBLECLK)) {
*eventType = QEvent::MouseButtonDblClick;
*eventType = nonClient ? QEvent::NonClientAreaMouseButtonDblClick :
QEvent::MouseButtonDblClick;
}
lastTime = messageTime;
lastButton = *mouseButton;
lastEvent = *eventType;
lastPos = globalPos;
}
}

View File

@ -106,7 +106,7 @@ while (query.next()) {
QVariant v = query.result()->handle();
if (qstrcmp(v.typeName(), "PGresult*") == 0) {
PGresult *handle = *static_cast<PGresult **>(v.data());
if (handle != 0) {
if (handle) {
// Do something...
}
}

View File

@ -51,10 +51,10 @@
//! [0]
QSqlDatabase db = ...;
QVariant v = db.driver()->handle();
if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*")==0) {
if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*") == 0) {
// v.data() returns a pointer to the handle
sqlite3 *handle = *static_cast<sqlite3 **>(v.data());
if (handle != 0) { // check that it is not NULL
if (handle) {
...
}
}
@ -62,13 +62,13 @@ if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*")==0) {
//! [1]
if (qstrcmp(v.typeName(), "PGconn*")) {
if (qstrcmp(v.typeName(), "PGconn*") == 0) {
PGconn *handle = *static_cast<PGconn **>(v.data());
if (handle != 0) ...
if (handle) ...
}
if (qstrcmp(v.typeName(), "MYSQL*")) {
if (qstrcmp(v.typeName(), "MYSQL*") == 0) {
MYSQL *handle = *static_cast<MYSQL **>(v.data());
if (handle != 0) ...
if (handle) ...
}
//! [1]

View File

@ -72,10 +72,10 @@ if (!q.execBatch())
//! [1]
QSqlQuery query = ...
QVariant v = query.result()->handle();
if (v.isValid() && qstrcmp(v.typeName(), "sqlite3_stmt*")) {
if (v.isValid() && qstrcmp(v.typeName(), "sqlite3_stmt*") == 0) {
// v.data() returns a pointer to the handle
sqlite3_stmt *handle = *static_cast<sqlite3_stmt **>(v.data());
if (handle != 0) { // check that it is not NULL
if (handle) {
...
}
}
@ -83,13 +83,13 @@ if (v.isValid() && qstrcmp(v.typeName(), "sqlite3_stmt*")) {
//! [2]
if (v.typeName() == "PGresult*") {
if (qstrcmp(v.typeName(), "PGresult*") == 0) {
PGresult *handle = *static_cast<PGresult **>(v.data());
if (handle != 0) ...
if (handle) ...
}
if (v.typeName() == "MYSQL_STMT*") {
if (qstrcmp(v.typeName(), "MYSQL_STMT*") == 0) {
MYSQL_STMT *handle = *static_cast<MYSQL_STMT **>(v.data());
if (handle != 0) ...
if (handle) ...
}
//! [2]

View File

@ -1405,10 +1405,10 @@ void WriteInitialization::writeProperties(const QString &varName,
propertyValue += QLatin1Char(')');
break;
case DomProperty::Float:
propertyValue = QString::number(p->elementFloat());
propertyValue = QString::number(p->elementFloat(), 'f', 8);
break;
case DomProperty::Double:
propertyValue = QString::number(p->elementDouble());
propertyValue = QString::number(p->elementDouble(), 'f', 15);
break;
case DomProperty::Char: {
const DomChar *c = p->elementChar();

View File

@ -110,7 +110,7 @@ QAccessibleTable::QAccessibleTable(QWidget *w)
bool QAccessibleTable::isValid() const
{
return (view() && !qobject_cast<QWidget*>(view())->d_func()->data.in_destructor);
return view() && !qt_widget_private(view())->data.in_destructor;
}
QAccessibleTable::~QAccessibleTable()
@ -1091,7 +1091,8 @@ void QAccessibleTableCell::setText(QAccessible::Text /*t*/, const QString &text)
bool QAccessibleTableCell::isValid() const
{
return view && view->model() && m_index.isValid();
return view && !qt_widget_private(view)->data.in_destructor
&& view->model() && m_index.isValid();
}
QAccessibleInterface *QAccessibleTableCell::parent() const
@ -1180,7 +1181,8 @@ void QAccessibleTableHeaderCell::setText(QAccessible::Text, const QString &)
bool QAccessibleTableHeaderCell::isValid() const
{
return view && view->model() && (index >= 0)
return view && !qt_widget_private(view)->data.in_destructor
&& view->model() && (index >= 0)
&& ((orientation == Qt::Horizontal) ? (index < view->model()->columnCount()) : (index < view->model()->rowCount()));
}

View File

@ -2123,7 +2123,6 @@ void QColorDialog::setVisible(bool visible)
}
/*!
\overload
\since 4.5
Opens the dialog and connects its colorSelected() signal to the slot specified

View File

@ -802,8 +802,6 @@ QFileDialog::Options QFileDialog::options() const
}
/*!
\overload
\since 4.5
This function connects one of its signals to the slot specified by \a receiver

View File

@ -931,7 +931,6 @@ QFontDialog::FontDialogOptions QFontDialog::options() const
/*!
\since 4.5
\overload
Opens the dialog and connects its fontSelected() signal to the slot specified
by \a receiver and \a member.

View File

@ -1070,7 +1070,6 @@ QString QInputDialog::cancelButtonText() const
/*!
\since 4.5
\overload
This function connects one of its signals to the slot specified by \a receiver
and \a member. The specific signal depends on the arguments that are specified

View File

@ -1500,8 +1500,6 @@ void QMessageBox::keyPressEvent(QKeyEvent *e)
}
/*!
\overload
Opens the dialog and connects its finished() or buttonClicked() signal to
the slot specified by \a receiver and \a member. If the slot in \a member
has a pointer for its first parameter the connection is to buttonClicked(),

View File

@ -865,7 +865,6 @@ void QProgressDialog::forceShow()
/*!
\since 4.5
\overload
Opens the dialog and connects its canceled() signal to the slot specified
by \a receiver and \a member.

View File

@ -1598,7 +1598,7 @@ QGraphicsItem::~QGraphicsItem()
#ifndef QT_NO_GESTURES
if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
if (QGestureManager *manager = QGestureManager::instance()) {
if (QGestureManager *manager = QGestureManager::instance(QGestureManager::DontForceCreation)) {
const auto types = d_ptr->gestureContext.keys(); // FIXME: iterate over the map directly?
for (Qt::GestureType type : types)
manager->cleanupCachedGestures(o, type);

View File

@ -297,6 +297,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
painterStateProtection(true),
sortCacheEnabled(false),
allItemsIgnoreTouchEvents(true),
focusOnTouch(true),
minimumRenderSize(0.0),
selectionChanging(0),
rectAdjust(2),
@ -2393,6 +2394,7 @@ void QGraphicsScene::clear()
d->allItemsIgnoreHoverEvents = true;
d->allItemsUseDefaultCursor = true;
d->allItemsIgnoreTouchEvents = true;
d->focusOnTouch = true;
}
/*!
@ -5854,6 +5856,41 @@ void QGraphicsScene::setMinimumRenderSize(qreal minSize)
update();
}
/*!
\property QGraphicsScene::focusOnTouch
\since 5.12
\brief whether items gain focus when receiving a \e {touch begin} event.
The usual behavior is to transfer focus only when an item is clicked. Often
a tap on a touchpad is interpreted as equivalent to a mouse click by the
operating system, generating a synthesized click event in response. However,
at least on macOS you can configure this behavior.
By default, QGraphicsScene also transfers focus when you touch on a trackpad
or similar. If the operating system is configured to not generate a
synthetic mouse click on tapping the trackpad, this is surprising. If the
operating system does generate synthetic mouse clicks on tapping the
trackpad, the focus transfer on starting a touch gesture is unnecessary.
With focusOnTouch switched off, QGraphicsScene behaves as one would expect
on macOS.
The default value is \c true, ensuring that the default behavior is just as
in Qt versions prior to 5.12. Set to \c false to prevent touch events from
triggering focus changes.
*/
bool QGraphicsScene::focusOnTouch() const
{
Q_D(const QGraphicsScene);
return d->focusOnTouch;
}
void QGraphicsScene::setFocusOnTouch(bool enabled)
{
Q_D(QGraphicsScene);
d->focusOnTouch = enabled;
}
void QGraphicsScenePrivate::addView(QGraphicsView *view)
{
views << view;
@ -6033,39 +6070,41 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
{
Q_Q(QGraphicsScene);
if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.constFirst() != origin) {
const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(),
firstTouchPoint.scenePos(),
static_cast<QWidget *>(touchEvent->target()));
}
if (focusOnTouch) {
if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.constFirst() != origin) {
const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(),
firstTouchPoint.scenePos(),
static_cast<QWidget *>(touchEvent->target()));
}
// Set focus on the topmost enabled item that can take focus.
bool setFocus = false;
// Set focus on the topmost enabled item that can take focus.
bool setFocus = false;
foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
setFocus = true;
if (item != q->focusItem())
q->setFocusItem(item, Qt::MouseFocusReason);
break;
}
}
if (item->isPanel())
break;
if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
break;
if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
// Make sure we don't clear focus.
setFocus = true;
if (item != q->focusItem())
q->setFocusItem(item, Qt::MouseFocusReason);
break;
}
}
if (item->isPanel())
break;
if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
break;
if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
// Make sure we don't clear focus.
setFocus = true;
break;
}
}
// If nobody could take focus, clear it.
if (!stickyFocus && !setFocus)
q->setFocusItem(0, Qt::MouseFocusReason);
// If nobody could take focus, clear it.
if (!stickyFocus && !setFocus)
q->setFocusItem(0, Qt::MouseFocusReason);
}
bool res = false;
bool eventAccepted = touchEvent->isAccepted();

View File

@ -106,6 +106,7 @@ class Q_WIDGETS_EXPORT QGraphicsScene : public QObject
Q_PROPERTY(bool sortCacheEnabled READ isSortCacheEnabled WRITE setSortCacheEnabled)
Q_PROPERTY(bool stickyFocus READ stickyFocus WRITE setStickyFocus)
Q_PROPERTY(qreal minimumRenderSize READ minimumRenderSize WRITE setMinimumRenderSize)
Q_PROPERTY(bool focusOnTouch READ focusOnTouch WRITE setFocusOnTouch)
public:
enum ItemIndexMethod {
@ -253,6 +254,9 @@ public:
qreal minimumRenderSize() const;
void setMinimumRenderSize(qreal minSize);
bool focusOnTouch() const;
void setFocusOnTouch(bool enabled);
public Q_SLOTS:
void update(const QRectF &rect = QRectF());
void invalidate(const QRectF &rect = QRectF(), SceneLayers layers = AllLayers);

View File

@ -114,7 +114,8 @@ public:
quint32 painterStateProtection : 1;
quint32 sortCacheEnabled : 1; // for compatibility
quint32 allItemsIgnoreTouchEvents : 1;
quint32 padding : 15;
quint32 focusOnTouch : 1;
quint32 padding : 14;
qreal minimumRenderSize;

View File

@ -131,11 +131,12 @@ QT_BEGIN_NAMESPACE
of the sibling that follows the parent.
\row \li Left \li Hides the children of the current item (if present)
by collapsing a branch.
\row \li Minus \li Same as LeftArrow.
\row \li Minus \li Same as Left.
\row \li Right \li Reveals the children of the current item (if present)
by expanding a branch.
\row \li Plus \li Same as RightArrow.
\row \li Asterisk \li Expands all children of the current item (if present).
\row \li Plus \li Same as Right.
\row \li Asterisk \li Expands the current item and all its children
(if present).
\row \li PageUp \li Moves the cursor up one page.
\row \li PageDown \li Moves the cursor down one page.
\row \li Home \li Moves the cursor to an item in the same column of the first

View File

@ -1345,7 +1345,6 @@ void QApplication::setGlobalStrut(const QSize& strut)
/*!
\fn QPalette QApplication::palette(const QWidget* widget)
\overload
If a \a widget is passed, the default palette for the widget's class is
returned. This may or may not be the application palette. In most cases
@ -4522,12 +4521,12 @@ void QApplicationPrivate::notifyDragStarted(const QDrag *drag)
#endif // QT_CONFIG(draganddrop)
#ifndef QT_NO_GESTURES
QGestureManager* QGestureManager::instance()
QGestureManager* QGestureManager::instance(InstanceCreation ic)
{
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
if (!qAppPriv)
return 0;
if (!qAppPriv->gestureManager)
if (!qAppPriv->gestureManager && ic == ForceCreation)
qAppPriv->gestureManager = new QGestureManager(qApp);
return qAppPriv->gestureManager;
}

View File

@ -773,7 +773,7 @@ void QGestureManager::recycle(QGesture *gesture)
bool QGestureManager::gesturePending(QObject *o)
{
const QGestureManager *gm = QGestureManager::instance();
const QGestureManager *gm = QGestureManager::instance(DontForceCreation);
return gm && gm->m_gestureOwners.key(o);
}

View File

@ -81,7 +81,9 @@ public:
bool filterEvent(QGraphicsObject *receiver, QEvent *event);
#endif // QT_CONFIG(graphicsview)
static QGestureManager* instance(); // declared in qapplication.cpp
enum InstanceCreation { ForceCreation, DontForceCreation };
static QGestureManager *instance(InstanceCreation ic = ForceCreation); // declared in qapplication.cpp
static bool gesturePending(QObject *o);
void cleanupCachedGestures(QObject *target, Qt::GestureType type);

View File

@ -1572,7 +1572,7 @@ QWidget::~QWidget()
#endif
#ifndef QT_NO_GESTURES
if (QGestureManager *manager = QGestureManager::instance()) {
if (QGestureManager *manager = QGestureManager::instance(QGestureManager::DontForceCreation)) {
// \forall Qt::GestureType type : ungrabGesture(type) (inlined)
for (auto it = d->gestureContext.keyBegin(), end = d->gestureContext.keyEnd(); it != end; ++it)
manager->cleanupCachedGestures(this, *it);
@ -6600,9 +6600,12 @@ QWidget *QWidgetPrivate::deepestFocusProxy() const
void QWidgetPrivate::setFocus_sys()
{
Q_Q(QWidget);
// Embedded native widget may have taken the focus; get it back to toplevel if that is the case
// Embedded native widget may have taken the focus; get it back to toplevel
// if that is the case (QTBUG-25852)
const QWidget *topLevel = q->window();
if (topLevel->windowType() != Qt::Popup) {
// Do not activate in case the popup menu opens another application (QTBUG-70810).
if (QGuiApplication::applicationState() == Qt::ApplicationActive
&& topLevel->windowType() != Qt::Popup) {
if (QWindow *nativeWindow = q->window()->windowHandle()) {
if (nativeWindow != QGuiApplication::focusWindow()
&& q->testAttribute(Qt::WA_WState_Created)) {

View File

@ -116,6 +116,8 @@
#include <QtWidgets/qtoolbar.h>
#endif
#include <QtGui/qscreen.h>
QT_BEGIN_NAMESPACE
using namespace QCss;
@ -954,7 +956,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
origin = Origin_Padding;
Origin clip = Origin_Border;
if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip)) {
QPixmap pixmap(uri);
QPixmap pixmap = QStyleSheetStyle::loadPixmap(uri, object);
if (!uri.isEmpty() && pixmap.isNull())
qWarning("Could not create pixmap from %s", qPrintable(QDir::toNativeSeparators(uri)));
bg = new QStyleSheetBackgroundData(brush, pixmap, repeat, alignment, origin, attachment, clip);
@ -997,7 +999,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
bd->bi = new QStyleSheetBorderImageData;
QStyleSheetBorderImageData *bi = bd->bi;
bi->pixmap = QPixmap(uri);
bi->pixmap = QStyleSheetStyle::loadPixmap(uri, object);
for (int i = 0; i < 4; i++)
bi->cuts[i] = cuts[i];
bi->horizStretch = horizStretch;
@ -1220,30 +1222,33 @@ void QRenderRule::drawBackgroundImage(QPainter *p, const QRect &rect, QPoint off
if (background()->attachment == Attachment_Fixed)
off = QPoint(0, 0);
QSize bgpSize = bgp.size() / bgp.devicePixelRatio();
int bgpHeight = bgpSize.height();
int bgpWidth = bgpSize.width();
QRect r = originRect(rect, background()->origin);
QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgp.size(), r);
QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgpSize, r);
QRect inter = aligned.translated(-off).intersected(r);
switch (background()->repeat) {
case Repeat_Y:
p->drawTiledPixmap(inter.x(), r.y(), inter.width(), r.height(), bgp,
inter.x() - aligned.x() + off.x(),
bgp.height() - int(aligned.y() - r.y()) % bgp.height() + off.y());
bgpHeight - int(aligned.y() - r.y()) % bgpHeight + off.y());
break;
case Repeat_X:
p->drawTiledPixmap(r.x(), inter.y(), r.width(), inter.height(), bgp,
bgp.width() - int(aligned.x() - r.x())%bgp.width() + off.x(),
bgpWidth - int(aligned.x() - r.x())%bgpWidth + off.x(),
inter.y() - aligned.y() + off.y());
break;
case Repeat_XY:
p->drawTiledPixmap(r, bgp,
QPoint(bgp.width() - int(aligned.x() - r.x())% bgp.width() + off.x(),
bgp.height() - int(aligned.y() - r.y())%bgp.height() + off.y()));
QPoint(bgpWidth - int(aligned.x() - r.x())% bgpWidth + off.x(),
bgpHeight - int(aligned.y() - r.y())%bgpHeight + off.y()));
break;
case Repeat_None:
default:
p->drawPixmap(inter.x(), inter.y(), bgp, inter.x() - aligned.x() + off.x(),
inter.y() - aligned.y() + off.y(), inter.width(), inter.height());
inter.y() - aligned.y() + off.y(), bgp.width() , bgp.height());
break;
}
@ -6118,6 +6123,28 @@ bool QStyleSheetStyle::isNaturalChild(const QObject *obj)
return false;
}
QPixmap QStyleSheetStyle::loadPixmap(const QString &fileName, const QObject *context)
{
qreal ratio = -1.0;
if (const QWidget *widget = qobject_cast<const QWidget *>(context)) {
if (QScreen *screen = QApplication::screenAt(widget->mapToGlobal(QPoint(0, 0))))
ratio = screen->devicePixelRatio();
}
if (ratio < 0) {
if (const QApplication *app = qApp)
ratio = app->devicePixelRatio();
else
ratio = 1.0;
}
qreal sourceDevicePixelRatio = 1.0;
QString resolvedFileName = qt_findAtNxFile(fileName, ratio, &sourceDevicePixelRatio);
QPixmap pixmap(resolvedFileName);
pixmap.setDevicePixelRatio(sourceDevicePixelRatio);
return pixmap;
}
QT_END_NAMESPACE
#include "moc_qstylesheetstyle_p.cpp"

View File

@ -167,6 +167,7 @@ private:
static Qt::Alignment resolveAlignment(Qt::LayoutDirection, Qt::Alignment);
static bool isNaturalChild(const QObject *obj);
static QPixmap loadPixmap(const QString &fileName, const QObject *context);
bool initObject(const QObject *obj) const;
public:
static int numinstances;

View File

@ -696,7 +696,6 @@ void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const
// If we are in a floating tab, init from the parent because the attributes and the geometry
// of the title bar should be taken from the floating window.
option->initFrom(floatingTab && !isFloating() ? parentWidget() : this);
option->fontMetrics = QFontMetrics(d->font);
option->rect = dwlayout->titleArea();
option->title = d->fixedWindowTitle;
option->closable = hasFeature(this, QDockWidget::DockWidgetClosable);
@ -1473,6 +1472,7 @@ void QDockWidget::closeEvent(QCloseEvent *event)
void QDockWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
Q_D(QDockWidget);
QDockWidgetLayout *layout
= qobject_cast<QDockWidgetLayout*>(this->layout());
@ -1493,7 +1493,11 @@ void QDockWidget::paintEvent(QPaintEvent *event)
// the title may wish to extend out to all sides (eg. Vista style)
QStyleOptionDockWidget titleOpt;
initStyleOption(&titleOpt);
p.setFont(d_func()->font);
if (font() == QApplication::font("QDockWidget")) {
titleOpt.fontMetrics = QFontMetrics(d->font);
p.setFont(d->font);
}
p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt);
}
}

View File

@ -437,8 +437,6 @@ bool QLineEdit::hasFrame() const
#if QT_CONFIG(action)
/*!
\overload
Adds the \a action to the list of actions at the \a position.
\since 5.2
@ -682,7 +680,8 @@ QSize QLineEdit::sizeHint() const
Q_D(const QLineEdit);
ensurePolished();
QFontMetrics fm(font());
int h = qMax(fm.height(), 14) + 2*d->verticalMargin
const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
int h = qMax(fm.height(), iconSize - 2) + 2*d->verticalMargin
+ d->topTextMargin + d->bottomTextMargin
+ d->topmargin + d->bottommargin;
int w = fm.horizontalAdvance(QLatin1Char('x')) * 17 + 2*d->horizontalMargin

View File

@ -441,7 +441,7 @@ QLineEditPrivate::SideWidgetParameters QLineEditPrivate::sideWidgetParameters()
{
Q_Q(const QLineEdit);
SideWidgetParameters result;
result.iconSize = q->height() < 34 ? 16 : 32;
result.iconSize = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
result.margin = result.iconSize / 4;
result.widgetWidth = result.iconSize + 6;
result.widgetHeight = result.iconSize + 2;

View File

@ -1741,8 +1741,6 @@ QMenu::~QMenu()
}
/*!
\overload
This convenience function creates a new action with \a text.
The function adds the newly created action to the menu's
list of actions, and returns it.

View File

@ -749,8 +749,6 @@ QMenuBar::~QMenuBar()
}
/*!
\overload
This convenience function creates a new action with \a text.
The function adds the newly created action to the menu's
list of actions, and returns it.

View File

@ -2338,8 +2338,6 @@ void QPlainTextEdit::wheelEvent(QWheelEvent *e)
#endif
/*!
\fn QPlainTextEdit::zoomIn(int range)
Zooms in on the text by making the base font size \a range
points larger and recalculating all font sizes to be the new size.
This does not change the size of any images.
@ -2352,10 +2350,6 @@ void QPlainTextEdit::zoomIn(int range)
}
/*!
\fn QPlainTextEdit::zoomOut(int range)
\overload
Zooms out on the text by making the base font size \a range points
smaller and recalculating all font sizes to be the new size. This
does not change the size of any images.

View File

@ -511,8 +511,6 @@ QString QTabWidget::tabText(int index) const
}
/*!
\overload
Sets the \a icon for the tab at position \a index.
*/
void QTabWidget::setTabIcon(int index, const QIcon &icon)

View File

@ -2310,8 +2310,6 @@ void QTextEdit::scrollToAnchor(const QString &name)
}
/*!
\fn QTextEdit::zoomIn(int range)
Zooms in on the text by making the base font size \a range
points larger and recalculating all font sizes to be the new size.
This does not change the size of any images.
@ -2324,10 +2322,6 @@ void QTextEdit::zoomIn(int range)
}
/*!
\fn QTextEdit::zoomOut(int range)
\overload
Zooms out on the text by making the base font size \a range points
smaller and recalculating all font sizes to be the new size. This
does not change the size of any images.

View File

@ -743,8 +743,6 @@ void QToolBar::clear()
}
/*!
\overload
Creates a new action with the given \a text. This action is added to
the end of the toolbar.
*/

View File

@ -37,6 +37,7 @@ public:
tst_QSortFilterProxyModelRegExp();
private slots:
void tst_invalid();
void tst_caseSensitivity();
};
tst_QSortFilterProxyModelRegExp::tst_QSortFilterProxyModelRegExp() :
@ -55,5 +56,14 @@ void tst_QSortFilterProxyModelRegExp::tst_invalid()
QCOMPARE(model.filterRegExp(), QRegExp());
}
void tst_QSortFilterProxyModelRegExp::tst_caseSensitivity()
{
const QLatin1String pattern("test");
QSortFilterProxyModel model;
model.setFilterCaseSensitivity(Qt::CaseInsensitive);
model.setFilterRegExp(pattern);
QCOMPARE(model.filterCaseSensitivity(), Qt::CaseInsensitive);
}
QTEST_MAIN(tst_QSortFilterProxyModelRegExp)
#include "tst_qsortfilterproxymodel_regexp.moc"

View File

@ -19,7 +19,7 @@ winrt
[graphicsViewClipping]
windows
winrt
rhel-7.4 ci
linux ci
[glFBOUseInGLWidget]
windows
winrt

View File

@ -1,7 +1,7 @@
/********************************************************************************
** Form generated from reading UI file 'buttongroup.ui'
**
** Created by: Qt User Interface Compiler version 5.10.1
** Created by: Qt User Interface Compiler version 5.12.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
@ -129,9 +129,9 @@ public:
sizePolicy3.setHeightForWidth(periodSpinBox->sizePolicy().hasHeightForWidth());
periodSpinBox->setSizePolicy(sizePolicy3);
periodSpinBox->setMinimumSize(QSize(0, 30));
periodSpinBox->setMinimum(-1);
periodSpinBox->setSingleStep(0.1);
periodSpinBox->setValue(-1);
periodSpinBox->setMinimum(-1.000000000000000);
periodSpinBox->setSingleStep(0.100000000000000);
periodSpinBox->setValue(-1.000000000000000);
formLayout->setWidget(0, QFormLayout::FieldRole, periodSpinBox);
@ -139,9 +139,9 @@ public:
amplitudeSpinBox->setObjectName(QString::fromUtf8("amplitudeSpinBox"));
amplitudeSpinBox->setEnabled(false);
amplitudeSpinBox->setMinimumSize(QSize(0, 30));
amplitudeSpinBox->setMinimum(-1);
amplitudeSpinBox->setSingleStep(0.1);
amplitudeSpinBox->setValue(-1);
amplitudeSpinBox->setMinimum(-1.000000000000000);
amplitudeSpinBox->setSingleStep(0.100000000000000);
amplitudeSpinBox->setValue(-1.000000000000000);
formLayout->setWidget(2, QFormLayout::FieldRole, amplitudeSpinBox);
@ -155,9 +155,9 @@ public:
overshootSpinBox->setObjectName(QString::fromUtf8("overshootSpinBox"));
overshootSpinBox->setEnabled(false);
overshootSpinBox->setMinimumSize(QSize(0, 30));
overshootSpinBox->setMinimum(-1);
overshootSpinBox->setSingleStep(0.1);
overshootSpinBox->setValue(-1);
overshootSpinBox->setMinimum(-1.000000000000000);
overshootSpinBox->setSingleStep(0.100000000000000);
overshootSpinBox->setValue(-1.000000000000000);
formLayout->setWidget(4, QFormLayout::FieldRole, overshootSpinBox);

View File

@ -1,7 +1,7 @@
/********************************************************************************
** Form generated from reading UI file 'qpagesetupwidget.ui'
**
** Created by: Qt User Interface Compiler version 5.9.0
** Created by: Qt User Interface Compiler version 5.12.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
@ -104,7 +104,7 @@ public:
horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
pageWidth = new QDoubleSpinBox(groupBox_2);
pageWidth->setObjectName(QString::fromUtf8("pageWidth"));
pageWidth->setMaximum(9999.99);
pageWidth->setMaximum(9999.989999999999782);
horizontalLayout_3->addWidget(pageWidth);
@ -115,7 +115,7 @@ public:
pageHeight = new QDoubleSpinBox(groupBox_2);
pageHeight->setObjectName(QString::fromUtf8("pageHeight"));
pageHeight->setMaximum(9999.99);
pageHeight->setMaximum(9999.989999999999782);
horizontalLayout_3->addWidget(pageHeight);
@ -199,7 +199,7 @@ public:
topMargin = new QDoubleSpinBox(groupBox);
topMargin->setObjectName(QString::fromUtf8("topMargin"));
topMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
topMargin->setMaximum(999.99);
topMargin->setMaximum(999.990000000000009);
gridLayout->addWidget(topMargin, 0, 1, 1, 1);
@ -212,7 +212,7 @@ public:
leftMargin = new QDoubleSpinBox(groupBox);
leftMargin->setObjectName(QString::fromUtf8("leftMargin"));
leftMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
leftMargin->setMaximum(999.99);
leftMargin->setMaximum(999.990000000000009);
horizontalLayout->addWidget(leftMargin);
@ -223,7 +223,7 @@ public:
rightMargin = new QDoubleSpinBox(groupBox);
rightMargin->setObjectName(QString::fromUtf8("rightMargin"));
rightMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
rightMargin->setMaximum(999.99);
rightMargin->setMaximum(999.990000000000009);
horizontalLayout->addWidget(rightMargin);
@ -241,7 +241,7 @@ public:
bottomMargin = new QDoubleSpinBox(groupBox);
bottomMargin->setObjectName(QString::fromUtf8("bottomMargin"));
bottomMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
bottomMargin->setMaximum(999.99);
bottomMargin->setMaximum(999.990000000000009);
gridLayout->addWidget(bottomMargin, 2, 1, 1, 1);

View File

@ -31,7 +31,7 @@
/********************************************************************************
** Form generated from reading UI file 'qtgradienteditor.ui'
**
** Created by: Qt User Interface Compiler version 5.0.0
** Created by: Qt User Interface Compiler version 5.12.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
@ -176,8 +176,8 @@ public:
spinBox1->setGeometry(QRect(279, 69, 73, 23));
spinBox1->setKeyboardTracking(false);
spinBox1->setDecimals(3);
spinBox1->setMaximum(1);
spinBox1->setSingleStep(0.01);
spinBox1->setMaximum(1.000000000000000);
spinBox1->setSingleStep(0.010000000000000);
label2 = new QLabel(QtGradientEditor);
label2->setObjectName(QString::fromUtf8("label2"));
label2->setGeometry(QRect(209, 99, 64, 23));
@ -186,8 +186,8 @@ public:
spinBox2->setGeometry(QRect(279, 99, 73, 23));
spinBox2->setKeyboardTracking(false);
spinBox2->setDecimals(3);
spinBox2->setMaximum(1);
spinBox2->setSingleStep(0.01);
spinBox2->setMaximum(1.000000000000000);
spinBox2->setSingleStep(0.010000000000000);
label3 = new QLabel(QtGradientEditor);
label3->setObjectName(QString::fromUtf8("label3"));
label3->setGeometry(QRect(209, 129, 64, 23));
@ -196,8 +196,8 @@ public:
spinBox3->setGeometry(QRect(279, 129, 73, 23));
spinBox3->setKeyboardTracking(false);
spinBox3->setDecimals(3);
spinBox3->setMaximum(1);
spinBox3->setSingleStep(0.01);
spinBox3->setMaximum(1.000000000000000);
spinBox3->setSingleStep(0.010000000000000);
label4 = new QLabel(QtGradientEditor);
label4->setObjectName(QString::fromUtf8("label4"));
label4->setGeometry(QRect(209, 159, 64, 23));
@ -206,8 +206,8 @@ public:
spinBox4->setGeometry(QRect(279, 159, 73, 23));
spinBox4->setKeyboardTracking(false);
spinBox4->setDecimals(3);
spinBox4->setMaximum(1);
spinBox4->setSingleStep(0.01);
spinBox4->setMaximum(1.000000000000000);
spinBox4->setSingleStep(0.010000000000000);
label5 = new QLabel(QtGradientEditor);
label5->setObjectName(QString::fromUtf8("label5"));
label5->setGeometry(QRect(209, 189, 64, 23));
@ -216,8 +216,8 @@ public:
spinBox5->setGeometry(QRect(279, 189, 73, 23));
spinBox5->setKeyboardTracking(false);
spinBox5->setDecimals(3);
spinBox5->setMaximum(1);
spinBox5->setSingleStep(0.01);
spinBox5->setMaximum(1.000000000000000);
spinBox5->setSingleStep(0.010000000000000);
gradientStopsWidget = new QtGradientStopsWidget(QtGradientEditor);
gradientStopsWidget->setObjectName(QString::fromUtf8("gradientStopsWidget"));
gradientStopsWidget->setGeometry(QRect(10, 225, 193, 67));
@ -390,10 +390,10 @@ public:
positionSpinBox->setObjectName(QString::fromUtf8("positionSpinBox"));
positionSpinBox->setKeyboardTracking(false);
positionSpinBox->setDecimals(3);
positionSpinBox->setMinimum(0);
positionSpinBox->setMaximum(1);
positionSpinBox->setSingleStep(0.01);
positionSpinBox->setValue(0);
positionSpinBox->setMinimum(0.000000000000000);
positionSpinBox->setMaximum(1.000000000000000);
positionSpinBox->setSingleStep(0.010000000000000);
positionSpinBox->setValue(0.000000000000000);
vboxLayout1->addWidget(positionSpinBox);

View File

@ -1,7 +1,7 @@
/********************************************************************************
** Form generated from reading UI file 'validators.ui'
**
** Created by: Qt User Interface Compiler version 5.10.0
** Created by: Qt User Interface Compiler version 5.12.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
@ -252,9 +252,9 @@ public:
doubleMinVal->setObjectName(QString::fromUtf8("doubleMinVal"));
sizePolicy.setHeightForWidth(doubleMinVal->sizePolicy().hasHeightForWidth());
doubleMinVal->setSizePolicy(sizePolicy);
doubleMinVal->setMinimum(-100000);
doubleMinVal->setMaximum(100000);
doubleMinVal->setValue(0);
doubleMinVal->setMinimum(-100000.000000000000000);
doubleMinVal->setMaximum(100000.000000000000000);
doubleMinVal->setValue(0.000000000000000);
gridLayout1->addWidget(doubleMinVal, 0, 1, 1, 1);
@ -281,9 +281,9 @@ public:
doubleMaxVal->setObjectName(QString::fromUtf8("doubleMaxVal"));
sizePolicy.setHeightForWidth(doubleMaxVal->sizePolicy().hasHeightForWidth());
doubleMaxVal->setSizePolicy(sizePolicy);
doubleMaxVal->setMinimum(-100000);
doubleMaxVal->setMaximum(100000);
doubleMaxVal->setValue(1000);
doubleMaxVal->setMinimum(-100000.000000000000000);
doubleMaxVal->setMaximum(100000.000000000000000);
doubleMaxVal->setValue(1000.000000000000000);
gridLayout1->addWidget(doubleMaxVal, 1, 1, 1, 1);

View File

@ -254,6 +254,7 @@ private slots:
void zeroScale();
void focusItemChangedSignal();
void minimumRenderSize();
void focusOnTouch();
// task specific tests below me
void task139710_bspTreeCrash();
@ -4758,6 +4759,41 @@ void tst_QGraphicsScene::minimumRenderSize()
QVERIFY(smallChild->repaints > smallerGrandChild->repaints);
}
void tst_QGraphicsScene::focusOnTouch()
{
QGraphicsScene scene;
QGraphicsView view(&scene);
scene.setSceneRect(0, 0, 100, 100);
QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);
rect->setFlag(QGraphicsItem::ItemIsFocusable, true);
view.show();
QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QVERIFY(!rect->hasFocus());
scene.setFocusOnTouch(false);
QTouchDevice device;
device.setType(QTouchDevice::TouchPad);
QList<QTouchEvent::TouchPoint> touchPoints;
QTouchEvent::TouchPoint point;
point.setScenePos(QPointF(10, 10));
point.setState(Qt::TouchPointPressed);
touchPoints.append(point);
QTouchEvent event(QEvent::TouchBegin, &device, Qt::NoModifier, Qt::TouchPointStates(),
touchPoints);
QApplication::sendEvent(&scene, &event);
QVERIFY(!rect->hasFocus());
scene.setFocusOnTouch(true);
QApplication::sendEvent(&scene, &event);
QVERIFY(rect->hasFocus());
}
void tst_QGraphicsScene::taskQTBUG_15977_renderWithDeviceCoordinateCache()
{
QGraphicsScene scene;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View File

@ -2,5 +2,6 @@
<RCC version="1.0">
<qresource>
<file>images/testimage.png</file>
<file>images/testimage@2x.png</file>
</qresource>
</RCC>

View File

@ -33,6 +33,7 @@
#include <QMetaObject>
#include <private/qstylesheetstyle_p.h>
#include <private/qhighdpiscaling_p.h>
#include <QtTest/private/qtesthelpers_p.h>
using namespace QTestPrivate;
@ -101,6 +102,9 @@ private slots:
void styleSheetTargetAttribute();
void unpolish();
void highdpiImages_data();
void highdpiImages();
private:
QColor COLOR(const QWidget& w) {
w.ensurePolished();
@ -2066,6 +2070,35 @@ void tst_QStyleSheetStyle::unpolish()
QCOMPARE(w.minimumWidth(), 0);
}
void tst_QStyleSheetStyle::highdpiImages_data()
{
QTest::addColumn<qreal>("screenFactor");
QTest::addColumn<QColor>("color");
QTest::newRow("highdpi") << 2.0 << QColor(0x00, 0xFF, 0x00);
QTest::newRow("lowdpi") << 1.0 << QColor(0xFF, 0x00, 0x00);
}
void tst_QStyleSheetStyle::highdpiImages()
{
QFETCH(qreal, screenFactor);
QFETCH(QColor, color);
QWidget w;
QScreen *screen = QGuiApplication::screenAt(w.pos());
QHighDpiScaling::setScreenFactor(screen, screenFactor);
w.setStyleSheet("QWidget { background-image: url(\":/images/testimage.png\"); }");
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));
QImage image(w.size(), QImage::Format_ARGB32);
w.render(&image);
QVERIFY(testForColors(image, color));
QHighDpiScaling::setScreenFactor(screen, 1.0);
QHighDpiScaling::updateHighDpiScaling(); // reset to normal
}
QTEST_MAIN(tst_QStyleSheetStyle)
#include "tst_qstylesheetstyle.moc"