Merge remote-tracking branch 'origin/stable' into dev
Manually changed enum to LibGL in
src/plugins/platforms/xcb/qglxintegration.cpp
Change-Id: If34ee6cce3d1d51fb4bb1fdfa59c30389ea0d207
bb10
commit
b5552bab40
|
|
@ -446,6 +446,15 @@ Android
|
|||
- Fonts:
|
||||
* [QTBUG-36789] Fixed support for Arabic text.
|
||||
|
||||
iOS
|
||||
---
|
||||
|
||||
- Support for input methods added.
|
||||
- Support for word completion and spell checking added.
|
||||
- Support for QClipboard added.
|
||||
- "Hide keyboard" gesture added.
|
||||
- Keyboard input is now sendt as input method events instead of key events.
|
||||
|
||||
Linux
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# W A R N I N G
|
||||
# -------------
|
||||
#
|
||||
# This file is not part of the Qt API. It exists purely as an
|
||||
# implementation detail. It may change from version to version
|
||||
# without notice, or even be removed.
|
||||
#
|
||||
# We mean it.
|
||||
#
|
||||
|
||||
load(qt_build_paths)
|
||||
|
||||
TEMPLATE = lib
|
||||
CONFIG -= qt
|
||||
|
||||
contains(QT_CONFIG, debug_and_release): CONFIG += debug_and_release
|
||||
contains(QT_CONFIG, build_all): CONFIG += build_all
|
||||
|
||||
DESTDIR = $$MODULE_BASE_OUTDIR/lib
|
||||
DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin
|
||||
|
||||
# Static builds always need to be installed, as the convenience libraries
|
||||
# are not linked to the final library in this case.
|
||||
installed|static: load(qt_installs)
|
||||
|
||||
TARGET = $$qtLibraryTarget($$TARGET)
|
||||
|
|
@ -18,7 +18,7 @@ QT_CPU_FEATURES = $$eval(QT_CPU_FEATURES.$$QT_ARCH)
|
|||
#
|
||||
# Set up compilers for SIMD (SSE/AVX, NEON etc)
|
||||
#
|
||||
*-g++*|intel_icc|*-clang*|*-qcc* {
|
||||
gcc { # includes intel_icc and clang variants
|
||||
sse2 {
|
||||
HEADERS += $$SSE2_HEADERS
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ equals(TEMPLATE, app):contains(QT, gui(-private)?) {
|
|||
# We do link and dependency resolution for the platform plugin
|
||||
# manually, since we know we always need the plugin, so we don't
|
||||
# need to generate an import for it.
|
||||
CONFIG -= import_qpa_plugin
|
||||
QTPLUGIN.platforms = -
|
||||
|
||||
!no_main_wrapper {
|
||||
# We use ld to rename the _main symbol to _qt_main, so that we don't get a symbol clash
|
||||
|
|
|
|||
|
|
@ -1116,7 +1116,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
//all files
|
||||
const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files"));
|
||||
for(int file = 0; file < files.count(); file++) {
|
||||
QString fn = files[file].toQString();
|
||||
QString fn = fileFixify(files[file].toQString(), Option::output_dir, input_dir);
|
||||
QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_DATA_FILE_REF." + bundle_data[i] + "-" + fn);
|
||||
bundle_file_refs += file_ref_key;
|
||||
t << "\t\t" << file_ref_key << " = {\n"
|
||||
|
|
|
|||
|
|
@ -1745,14 +1745,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||
if (target == TargetSuper) {
|
||||
if (m_superfile.isEmpty()) {
|
||||
m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
|
||||
printf("Info: creating super cache file %s\n", qPrintable(m_superfile));
|
||||
printf("Info: creating super cache file %s\n", qPrintable(QDir::toNativeSeparators(m_superfile)));
|
||||
valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
|
||||
}
|
||||
fn = m_superfile;
|
||||
} else if (target == TargetCache) {
|
||||
if (m_cachefile.isEmpty()) {
|
||||
m_cachefile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.cache"));
|
||||
printf("Info: creating cache file %s\n", qPrintable(m_cachefile));
|
||||
printf("Info: creating cache file %s\n", qPrintable(QDir::toNativeSeparators(m_cachefile)));
|
||||
valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
|
||||
// We could update m_{source,build}Root and m_featureRoots here, or even
|
||||
// "re-home" our rootEnv, but this doesn't sound too useful - if somebody
|
||||
|
|
@ -1766,7 +1766,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||
if (fn.isEmpty())
|
||||
fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
|
||||
if (!m_vfs->exists(fn)) {
|
||||
printf("Info: creating stash file %s\n", qPrintable(fn));
|
||||
printf("Info: creating stash file %s\n", qPrintable(QDir::toNativeSeparators(fn)));
|
||||
valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
TARGET = qtharfbuzzng
|
||||
TEMPLATE = lib
|
||||
|
||||
CONFIG += \
|
||||
static \
|
||||
hide_symbols \
|
||||
exceptions_off rtti_off
|
||||
CONFIG -= qt
|
||||
|
||||
contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release
|
||||
contains(QT_CONFIG, build_all):CONFIG += build_all
|
||||
|
||||
DESTDIR = $$QT_BUILD_TREE/lib
|
||||
load(qt_helper_lib)
|
||||
|
||||
DEFINES += HAVE_CONFIG_H
|
||||
HEADERS += $$PWD/src/config.h
|
||||
|
|
@ -133,5 +128,3 @@ mac {
|
|||
# even in 10.8 where they were also made available stand-alone.
|
||||
LIBS_PRIVATE += -framework ApplicationServices
|
||||
}
|
||||
|
||||
TARGET = $$TARGET$$qtPlatformTargetSuffix()
|
||||
|
|
|
|||
|
|
@ -690,13 +690,10 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||
*/
|
||||
CFDictionaryRef attributes = CTRunGetAttributes (run);
|
||||
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
|
||||
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
|
||||
|
||||
CFRange range = CTRunGetStringRange (run);
|
||||
if (!CFEqual (run_cg_font, face_data->cg_font))
|
||||
if (!CFEqual (run_ct_font, font_data->ct_font))
|
||||
{
|
||||
CFRelease (run_cg_font);
|
||||
|
||||
buffer->ensure (buffer->len + range.length);
|
||||
if (buffer->in_error)
|
||||
FAIL ("Buffer resize failed");
|
||||
|
|
@ -731,7 +728,6 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
CFRelease (run_cg_font);
|
||||
|
||||
/* CoreText throws away the PDF token, while the OpenType backend will add a zero-advance
|
||||
* glyph for this. We need to make sure the two produce the same output. */
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
CONFIG += installed
|
||||
include (../config.pri)
|
||||
|
||||
INCLUDEPATH += \
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
TEMPLATE = lib
|
||||
CONFIG += static
|
||||
TARGET = $$qtLibraryTarget(preprocessor)
|
||||
|
||||
include(../../config.pri)
|
||||
|
||||
INCLUDEPATH = $$ANGLE_DIR/src/compiler/preprocessor
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
TEMPLATE = lib
|
||||
CONFIG += static
|
||||
TARGET = $$qtLibraryTarget(translator)
|
||||
|
||||
include(../config.pri)
|
||||
|
||||
# Mingw 4.7 chokes on implicit move semantics, so disable C++11 here
|
||||
|
|
|
|||
|
|
@ -59,17 +59,10 @@ CONFIG(debug, debug|release) {
|
|||
}
|
||||
|
||||
# c++11 is needed by MinGW to get support for unordered_map.
|
||||
CONFIG -= qt
|
||||
CONFIG += stl exceptions c++11
|
||||
|
||||
contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release
|
||||
contains(QT_CONFIG, build_all):CONFIG += build_all
|
||||
|
||||
INCLUDEPATH += . .. $$PWD/../include
|
||||
|
||||
DESTDIR = $$QT_BUILD_TREE/lib
|
||||
DLLDESTDIR = $$QT_BUILD_TREE/bin
|
||||
|
||||
msvc {
|
||||
# Disabled Warnings:
|
||||
# 4100: 'identifier' : unreferenced formal parameter
|
||||
|
|
@ -107,3 +100,5 @@ gcc {
|
|||
|
||||
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
|
||||
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
|
||||
|
||||
load(qt_helper_lib)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
TEMPLATE = lib
|
||||
TARGET = $$qtLibraryTarget(d3dcompiler_qt)
|
||||
|
||||
TARGET = d3dcompiler_qt
|
||||
CONFIG += installed
|
||||
include(../config.pri)
|
||||
CONFIG += qt
|
||||
|
||||
CONFIG += qt
|
||||
QT = core
|
||||
DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
|
||||
SOURCES += main.cpp
|
||||
|
|
@ -16,5 +15,3 @@ winrt:equals(WINSDK_VER, 8.1) {
|
|||
|
||||
# __stdcall exports get mangled, so use a def file
|
||||
DEF_FILE += $${TARGET}.def
|
||||
|
||||
load(qt_installs)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
TEMPLATE = lib
|
||||
TARGET = $$qtLibraryTarget(libEGL)
|
||||
|
||||
CONFIG += installed
|
||||
include(../common/common.pri)
|
||||
|
||||
angle_d3d11: \
|
||||
|
|
@ -30,8 +28,6 @@ SOURCES += \
|
|||
mingw:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}_mingw32.def
|
||||
}
|
||||
|
||||
load(qt_installs)
|
||||
|
||||
egl_headers.files = \
|
||||
$$ANGLE_DIR/include/EGL/egl.h \
|
||||
$$ANGLE_DIR/include/EGL/eglext.h \
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
TEMPLATE = lib
|
||||
TARGET = $$qtLibraryTarget(libGLESv2)
|
||||
CONFIG += simd
|
||||
|
||||
CONFIG += simd installed
|
||||
include(../common/common.pri)
|
||||
|
||||
INCLUDEPATH += $$OUT_PWD/.. $$ANGLE_DIR/src/libGLESv2
|
||||
|
|
@ -13,8 +10,8 @@ angle_d3d11: \
|
|||
LIBS_PRIVATE += -ld3d9
|
||||
|
||||
LIBS_PRIVATE += -ldxguid
|
||||
STATICLIBS = translator preprocessor
|
||||
|
||||
STATICLIBS = translator preprocessor
|
||||
for(libname, STATICLIBS) {
|
||||
# Appends 'd' to the library for debug builds and builds up the fully
|
||||
# qualified path to pass to the linker.
|
||||
|
|
@ -238,8 +235,6 @@ for (vs, VERTEX_SHADERS_CLEAR) {
|
|||
angle_d3d11: QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
|
||||
}
|
||||
|
||||
load(qt_installs)
|
||||
|
||||
khr_headers.files = $$ANGLE_DIR/include/KHR/khrplatform.h
|
||||
khr_headers.path = $$[QT_INSTALL_HEADERS]/QtANGLE/KHR
|
||||
gles2_headers.files = \
|
||||
|
|
@ -248,5 +243,3 @@ gles2_headers.files = \
|
|||
$$ANGLE_DIR/include/GLES2/gl2platform.h
|
||||
gles2_headers.path = $$[QT_INSTALL_HEADERS]/QtANGLE/GLES2
|
||||
INSTALLS += khr_headers gles2_headers
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ qhp.QtCore.subprojects.classes.sortPages = true
|
|||
|
||||
tagfile = ../../../doc/qtcore/qtcore.tags
|
||||
|
||||
depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtqml qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake
|
||||
depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake
|
||||
# depends += qtqml # Qt namespace collides with QtQml::Qt, see QTBUG-38630
|
||||
|
||||
headerdirs += ..
|
||||
|
||||
|
|
|
|||
|
|
@ -365,6 +365,11 @@ QStringList QFileSelectorPrivate::platformSelectors()
|
|||
ret << QStringLiteral("windows");
|
||||
# if defined(Q_OS_WINCE)
|
||||
ret << QStringLiteral("wince");
|
||||
# elif defined(Q_OS_WINRT)
|
||||
ret << QStringLiteral("winrt");
|
||||
# if defined(Q_OS_WINPHONE)
|
||||
ret << QStringLiteral("winphone");
|
||||
# endif
|
||||
# endif
|
||||
#elif defined(Q_OS_UNIX)
|
||||
ret << QStringLiteral("unix");
|
||||
|
|
|
|||
|
|
@ -62,6 +62,12 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
|
|||
by a string - at runtime. Whether a category should be actually logged or
|
||||
not can be checked with the \l isEnabled() methods.
|
||||
|
||||
All objects are meant to be configured by a common registry (see also
|
||||
\l{Configuring Categories}). Different objects can also represent the same
|
||||
category. It's therefore not recommended to export objects across module
|
||||
boundaries, nor to manipulate the objects directly, nor to inherit from
|
||||
QLoggingCategory.
|
||||
|
||||
\section1 Creating category objects
|
||||
|
||||
The Q_LOGGING_CATEGORY() and the Q_DECLARE_LOGGING_CATEGORY() macros
|
||||
|
|
|
|||
|
|
@ -325,6 +325,7 @@ private:
|
|||
friend class QGraphicsViewPrivate;
|
||||
friend class QGraphicsScene;
|
||||
friend class QGraphicsScenePrivate;
|
||||
friend class QWidgetWindow;
|
||||
#ifndef QT_NO_GESTURES
|
||||
friend class QGestureManager;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -777,6 +777,7 @@ struct VariantData
|
|||
const void *data;
|
||||
const uint flags;
|
||||
private:
|
||||
// copy constructor allowed to be implicit to silence level 4 warning from MSVC
|
||||
VariantData &operator=(const VariantData &) Q_DECL_EQ_DELETE;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -125,11 +125,9 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
|
|||
or writing to the shared memory, and remember to release the lock
|
||||
with unlock() after you are done.
|
||||
|
||||
Unlike QtSharedMemory, QSharedMemory automatically destroys the
|
||||
shared memory segment when the last instance of QSharedMemory is
|
||||
detached from the segment, and no references to the segment
|
||||
remain. Do not mix using QtSharedMemory and QSharedMemory. Port
|
||||
everything to QSharedMemory.
|
||||
QSharedMemory automatically destroys the shared memory segment when
|
||||
the last instance of QSharedMemory is detached from the segment, and
|
||||
no references to the segment remain.
|
||||
|
||||
\warning QSharedMemory changes the key in a Qt-specific way, unless otherwise
|
||||
specified. Interoperation with non-Qt applications is achieved by first creating
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ QTimeZonePrivate *QMacTimeZonePrivate::clone()
|
|||
void QMacTimeZonePrivate::init(const QByteArray &ianaId)
|
||||
{
|
||||
if (availableTimeZoneIds().contains(ianaId)) {
|
||||
m_nstz = [NSTimeZone timeZoneWithName:QCFString::toNSString(QString::fromUtf8(ianaId))];
|
||||
m_nstz = [[NSTimeZone timeZoneWithName:QCFString::toNSString(QString::fromUtf8(ianaId))] retain];
|
||||
if (m_nstz)
|
||||
m_id = ianaId;
|
||||
}
|
||||
|
|
@ -142,7 +142,6 @@ QString QMacTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
|
|||
NSString *macLocaleCode = QCFString::toNSString(locale.name());
|
||||
NSLocale *macLocale = [[NSLocale alloc] initWithLocaleIdentifier:macLocaleCode];
|
||||
const QString result = QCFString::toQString([m_nstz localizedName:style locale:macLocale]);
|
||||
[macLocaleCode release];
|
||||
[macLocale release];
|
||||
return result;
|
||||
}
|
||||
|
|
@ -192,7 +191,6 @@ QTimeZonePrivate::Data QMacTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
|
|||
data.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:date];
|
||||
data.standardTimeOffset = data.offsetFromUtc - data.daylightTimeOffset;
|
||||
data.abbreviation = QCFString::toQString([m_nstz abbreviationForDate:date]);
|
||||
[date release];
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
@ -203,8 +201,6 @@ bool QMacTimeZonePrivate::hasTransitions() const
|
|||
NSDate *epoch = [NSDate dateWithTimeIntervalSince1970:0];
|
||||
const NSDate *date = [m_nstz nextDaylightSavingTimeTransitionAfterDate:epoch];
|
||||
const bool result = ([date timeIntervalSince1970] > [epoch timeIntervalSince1970]);
|
||||
[epoch release];
|
||||
[date release];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +220,6 @@ QTimeZonePrivate::Data QMacTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
|
|||
tran.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:nextDate];
|
||||
tran.standardTimeOffset = tran.offsetFromUtc - tran.daylightTimeOffset;
|
||||
tran.abbreviation = QCFString::toQString([m_nstz abbreviationForDate:nextDate]);
|
||||
[nextDate release];
|
||||
return tran;
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +241,6 @@ QTimeZonePrivate::Data QMacTimeZonePrivate::previousTransition(qint64 beforeMSec
|
|||
nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
|
||||
nextSecs = [nextDate timeIntervalSince1970];
|
||||
}
|
||||
[nextDate release];
|
||||
}
|
||||
if (secsList.size() >= 1)
|
||||
return data(qint64(secsList.last()) * 1000);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ static int global_ser_no = 0;
|
|||
QBlittablePlatformPixmap::QBlittablePlatformPixmap()
|
||||
: QPlatformPixmap(QPlatformPixmap::PixmapType,BlitterClass)
|
||||
, m_alpha(false)
|
||||
, m_devicePixelRatio(1.0)
|
||||
#ifdef QT_BLITTER_RASTEROVERLAY
|
||||
,m_rasterOverlay(0), m_unmergedCopy(0)
|
||||
#endif //QT_BLITTER_RASTEROVERLAY
|
||||
|
|
@ -121,7 +122,7 @@ int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) con
|
|||
case QPaintDevice::PdmPhysicalDpiY:
|
||||
return qt_defaultDpiY();
|
||||
case QPaintDevice::PdmDevicePixelRatio:
|
||||
return 1;
|
||||
return devicePixelRatio();
|
||||
default:
|
||||
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
|
||||
break;
|
||||
|
|
@ -178,6 +179,7 @@ void QBlittablePlatformPixmap::fromImage(const QImage &image,
|
|||
Qt::ImageConversionFlags flags)
|
||||
{
|
||||
m_alpha = image.hasAlphaChannel();
|
||||
m_devicePixelRatio = image.devicePixelRatio();
|
||||
resize(image.width(),image.height());
|
||||
markRasterOverlay(QRect(0,0,w,h));
|
||||
QImage *thisImg = buffer();
|
||||
|
|
|
|||
|
|
@ -199,19 +199,13 @@ public:
|
|||
|
||||
enum OpenGLModuleType {
|
||||
LibGL,
|
||||
LibGLES,
|
||||
|
||||
// ###
|
||||
DesktopGL = LibGL,
|
||||
GLES2 = LibGLES
|
||||
LibGLES
|
||||
};
|
||||
|
||||
static OpenGLModuleType openGLModuleType();
|
||||
|
||||
bool isOpenGLES() const;
|
||||
|
||||
bool isES() const { return isOpenGLES(); } // ###
|
||||
|
||||
Q_SIGNALS:
|
||||
void aboutToBeDestroyed();
|
||||
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ Q_SIGNALS:
|
|||
void screenChanged(QScreen *screen);
|
||||
void modalityChanged(Qt::WindowModality modality);
|
||||
void windowStateChanged(Qt::WindowState windowState);
|
||||
void windowTitleChanged(const QString &title);
|
||||
Q_REVISION(2) void windowTitleChanged(const QString &title);
|
||||
|
||||
void xChanged(int arg);
|
||||
void yChanged(int arg);
|
||||
|
|
|
|||
|
|
@ -1112,6 +1112,9 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
|
|||
\fn QImage QOpenGLFramebufferObject::toImage() const
|
||||
|
||||
Returns the contents of this framebuffer object as a QImage.
|
||||
|
||||
Will try to return a premultiplied ARBG32 or RGB32 image. Since 5.2 it will fall back to
|
||||
a premultiplied RGBA8888 or RGBx8888 image when reading to ARGB32 is not supported.
|
||||
*/
|
||||
QImage QOpenGLFramebufferObject::toImage() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1709,6 +1709,163 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
|
|||
}
|
||||
} else {
|
||||
//we are zooming less than 8x, use 4bit precision
|
||||
|
||||
if (blendType != BlendTransformedBilinearTiled) {
|
||||
#define BILINEAR_ROTATE_BOUNDS_PROLOG \
|
||||
while (b < end) { \
|
||||
int x1 = (fx >> 16); \
|
||||
int x2; \
|
||||
int y1 = (fy >> 16); \
|
||||
int y2; \
|
||||
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); \
|
||||
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); \
|
||||
if (x1 != x2 && y1 != y2) \
|
||||
break; \
|
||||
const uint *s1 = (const uint *)data->texture.scanLine(y1); \
|
||||
const uint *s2 = (const uint *)data->texture.scanLine(y2); \
|
||||
uint tl = s1[x1]; \
|
||||
uint tr = s1[x2]; \
|
||||
uint bl = s2[x1]; \
|
||||
uint br = s2[x2]; \
|
||||
int distx = (fx & 0x0000ffff) >> 12; \
|
||||
int disty = (fy & 0x0000ffff) >> 12; \
|
||||
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \
|
||||
fx += fdx; \
|
||||
fy += fdy; \
|
||||
++b; \
|
||||
} \
|
||||
uint *boundedEnd = end - 3; \
|
||||
boundedEnd -= 3;
|
||||
|
||||
#if defined(__SSE2__)
|
||||
BILINEAR_ROTATE_BOUNDS_PROLOG
|
||||
|
||||
const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
|
||||
const __m128i v_256 = _mm_set1_epi16(256);
|
||||
__m128i v_fdx = _mm_set1_epi32(fdx*4);
|
||||
__m128i v_fdy = _mm_set1_epi32(fdy*4);
|
||||
|
||||
const uchar *textureData = data->texture.imageData;
|
||||
const int bytesPerLine = data->texture.bytesPerLine;
|
||||
|
||||
union Vect_buffer { __m128i vect; qint32 i[4]; };
|
||||
Vect_buffer v_fx, v_fy;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
v_fx.i[i] = fx;
|
||||
v_fy.i[i] = fy;
|
||||
fx += fdx;
|
||||
fy += fdy;
|
||||
}
|
||||
|
||||
while (b < boundedEnd) {
|
||||
if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2)
|
||||
break;
|
||||
if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1)
|
||||
break;
|
||||
if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2)
|
||||
break;
|
||||
if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1)
|
||||
break;
|
||||
|
||||
Vect_buffer tl, tr, bl, br;
|
||||
Vect_buffer v_fx_shifted, v_fy_shifted;
|
||||
v_fx_shifted.vect = _mm_srli_epi32(v_fx.vect, 16);
|
||||
v_fy_shifted.vect = _mm_srli_epi32(v_fy.vect, 16);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
const int x1 = v_fx_shifted.i[i];
|
||||
const int y1 = v_fy_shifted.i[i];
|
||||
const uchar *sl = textureData + bytesPerLine * y1;
|
||||
const uint *s1 = (const uint *)sl;
|
||||
const uint *s2 = (const uint *)(sl + bytesPerLine);
|
||||
tl.i[i] = s1[x1];
|
||||
tr.i[i] = s1[x1+1];
|
||||
bl.i[i] = s2[x1];
|
||||
br.i[i] = s2[x1+1];
|
||||
}
|
||||
__m128i v_distx = _mm_srli_epi16(v_fx.vect, 12);
|
||||
__m128i v_disty = _mm_srli_epi16(v_fy.vect, 12);
|
||||
v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
|
||||
v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
|
||||
v_disty = _mm_shufflehi_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
|
||||
v_disty = _mm_shufflelo_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
|
||||
|
||||
interpolate_4_pixels_16_sse2(tl.vect, tr.vect, bl.vect, br.vect, v_distx, v_disty, colorMask, v_256, b);
|
||||
b+=4;
|
||||
v_fx.vect = _mm_add_epi32(v_fx.vect, v_fdx);
|
||||
v_fy.vect = _mm_add_epi32(v_fy.vect, v_fdy);
|
||||
}
|
||||
fx = v_fx.i[0];
|
||||
fy = v_fy.i[0];
|
||||
#elif defined(__ARM_NEON__)
|
||||
BILINEAR_ROTATE_BOUNDS_PROLOG
|
||||
|
||||
const int16x8_t colorMask = vdupq_n_s16(0x00ff);
|
||||
const int16x8_t invColorMask = vmvnq_s16(colorMask);
|
||||
const int16x8_t v_256 = vdupq_n_s16(256);
|
||||
int32x4_t v_fdx = vdupq_n_s32(fdx*4);
|
||||
int32x4_t v_fdy = vdupq_n_s32(fdy*4);
|
||||
|
||||
const uchar *textureData = data->texture.imageData;
|
||||
const int bytesPerLine = data->texture.bytesPerLine;
|
||||
|
||||
union Vect_buffer { int32x4_t vect; quint32 i[4]; };
|
||||
Vect_buffer v_fx, v_fy;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
v_fx.i[i] = fx;
|
||||
v_fy.i[i] = fy;
|
||||
fx += fdx;
|
||||
fy += fdy;
|
||||
}
|
||||
|
||||
const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
|
||||
|
||||
while (b < boundedEnd) {
|
||||
if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2)
|
||||
break;
|
||||
if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1)
|
||||
break;
|
||||
if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2)
|
||||
break;
|
||||
if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1)
|
||||
break;
|
||||
|
||||
Vect_buffer tl, tr, bl, br;
|
||||
|
||||
Vect_buffer v_fx_shifted, v_fy_shifted;
|
||||
v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16);
|
||||
v_fy_shifted.vect = vshrq_n_s32(v_fy.vect, 16);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
const int x1 = v_fx_shifted.i[i];
|
||||
const int y1 = v_fy_shifted.i[i];
|
||||
const uchar *sl = textureData + bytesPerLine * y1;
|
||||
const uint *s1 = (const uint *)sl;
|
||||
const uint *s2 = (const uint *)(sl + bytesPerLine);
|
||||
tl.i[i] = s1[x1];
|
||||
tr.i[i] = s1[x1+1];
|
||||
bl.i[i] = s2[x1];
|
||||
br.i[i] = s2[x1+1];
|
||||
}
|
||||
|
||||
int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12);
|
||||
int32x4_t v_disty = vshrq_n_s32(vandq_s32(v_fy.vect, v_ffff_mask), 12);
|
||||
v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
|
||||
v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
|
||||
int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
|
||||
|
||||
interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b);
|
||||
b+=4;
|
||||
v_fx.vect = vaddq_s32(v_fx.vect, v_fdx);
|
||||
v_fy.vect = vaddq_s32(v_fy.vect, v_fdy);
|
||||
}
|
||||
fx = v_fx.i[0];
|
||||
fy = v_fy.i[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
while (b < end) {
|
||||
int x1 = (fx >> 16);
|
||||
int x2;
|
||||
|
|
|
|||
|
|
@ -147,8 +147,9 @@ static inline uint line_emulation(uint emulation)
|
|||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
static bool qt_painter_thread_test(int devType, const char *what)
|
||||
static bool qt_painter_thread_test(int devType, int engineType, const char *what)
|
||||
{
|
||||
const QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
|
||||
switch (devType) {
|
||||
case QInternal::Image:
|
||||
case QInternal::Printer:
|
||||
|
|
@ -157,8 +158,13 @@ static bool qt_painter_thread_test(int devType, const char *what)
|
|||
break;
|
||||
default:
|
||||
if (QThread::currentThread() != qApp->thread()
|
||||
&& (devType!=QInternal::Pixmap || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps))
|
||||
&& (devType!=QInternal::OpenGL || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL))) {
|
||||
// pixmaps cannot be targets unless threaded pixmaps are supported
|
||||
&& (devType != QInternal::Pixmap || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedPixmaps))
|
||||
// framebuffer objects and such cannot be targets unless threaded GL is supported
|
||||
&& (devType != QInternal::OpenGL || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedOpenGL))
|
||||
// widgets cannot be targets except for QGLWidget
|
||||
&& (devType != QInternal::Widget || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedOpenGL)
|
||||
|| (engineType != QPaintEngine::OpenGL && engineType != QPaintEngine::OpenGL2))) {
|
||||
qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -5054,7 +5060,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
|
|||
return;
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
qt_painter_thread_test(d->device->devType(), "drawPixmap()");
|
||||
qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawPixmap()");
|
||||
#endif
|
||||
|
||||
if (d->extended) {
|
||||
|
|
@ -5125,7 +5131,7 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
|
|||
if (!d->engine || pm.isNull())
|
||||
return;
|
||||
#ifndef QT_NO_DEBUG
|
||||
qt_painter_thread_test(d->device->devType(), "drawPixmap()");
|
||||
qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawPixmap()");
|
||||
#endif
|
||||
|
||||
qreal x = r.x();
|
||||
|
|
@ -6612,7 +6618,7 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
|
|||
return;
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()");
|
||||
qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawTiledPixmap()");
|
||||
#endif
|
||||
|
||||
qreal sw = pixmap.width();
|
||||
|
|
|
|||
|
|
@ -1335,6 +1335,15 @@ QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &fami
|
|||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some font engines like the windows font engine
|
||||
* can not reliable create outline paths
|
||||
*/
|
||||
bool QFontEngine::hasUnreliableGlyphOutline() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QFixed QFontEngine::lastRightBearing(const QGlyphLayout &glyphs, bool round)
|
||||
{
|
||||
if (glyphs.numGlyphs >= 1) {
|
||||
|
|
|
|||
|
|
@ -450,6 +450,7 @@ static void scaleOutline(FT_Face face, FT_GlyphSlot g, FT_Fixed x_scale, FT_Fixe
|
|||
}
|
||||
}
|
||||
|
||||
#define GLYPH2PATH_DEBUG QT_NO_QDEBUG_MACRO // qDebug
|
||||
void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale)
|
||||
{
|
||||
const qreal factor = 1/64.;
|
||||
|
|
@ -461,22 +462,32 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
|
|||
int i = 0;
|
||||
for (int j = 0; j < g->outline.n_contours; ++j) {
|
||||
int last_point = g->outline.contours[j];
|
||||
QPointF start = cp + QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
|
||||
if(!(g->outline.tags[i] & 1)) {
|
||||
start += cp + QPointF(g->outline.points[last_point].x*factor, -g->outline.points[last_point].y*factor);
|
||||
start /= 2;
|
||||
GLYPH2PATH_DEBUG() << "contour:" << i << "to" << last_point;
|
||||
QPointF start = QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
|
||||
if (!(g->outline.tags[i] & 1)) { // start point is not on curve:
|
||||
if (!(g->outline.tags[last_point] & 1)) { // end point is not on curve:
|
||||
GLYPH2PATH_DEBUG() << " start and end point are not on curve";
|
||||
start = (QPointF(g->outline.points[last_point].x*factor,
|
||||
-g->outline.points[last_point].y*factor) + start) / 2.0;
|
||||
} else {
|
||||
GLYPH2PATH_DEBUG() << " end point is on curve, start is not";
|
||||
start = QPointF(g->outline.points[last_point].x*factor,
|
||||
-g->outline.points[last_point].y*factor);
|
||||
}
|
||||
--i; // to use original start point as control point below
|
||||
}
|
||||
// qDebug("contour: %d -- %d", i, g->outline.contours[j]);
|
||||
// qDebug("first point at %f %f", start.x(), start.y());
|
||||
path->moveTo(start);
|
||||
start += cp;
|
||||
GLYPH2PATH_DEBUG() << " start at" << start;
|
||||
|
||||
path->moveTo(start);
|
||||
QPointF c[4];
|
||||
c[0] = start;
|
||||
int n = 1;
|
||||
while (i < last_point) {
|
||||
++i;
|
||||
c[n] = cp + QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
|
||||
// qDebug() << " i=" << i << " flag=" << (int)g->outline.tags[i] << "point=" << c[n];
|
||||
GLYPH2PATH_DEBUG() << " " << i << c[n] << "tag =" << (int)g->outline.tags[i]
|
||||
<< ": on curve =" << (bool)(g->outline.tags[i] & 1);
|
||||
++n;
|
||||
switch (g->outline.tags[i] & 3) {
|
||||
case 2:
|
||||
|
|
@ -498,7 +509,7 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
|
|||
case 1:
|
||||
case 3:
|
||||
if (n == 2) {
|
||||
// qDebug() << "lineTo" << c[1];
|
||||
GLYPH2PATH_DEBUG() << " lineTo" << c[1];
|
||||
path->lineTo(c[1]);
|
||||
c[0] = c[1];
|
||||
n = 1;
|
||||
|
|
@ -510,13 +521,14 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
|
|||
}
|
||||
break;
|
||||
}
|
||||
// qDebug() << "cubicTo" << c[1] << c[2] << c[3];
|
||||
GLYPH2PATH_DEBUG() << " cubicTo" << c[1] << c[2] << c[3];
|
||||
path->cubicTo(c[1], c[2], c[3]);
|
||||
c[0] = c[3];
|
||||
n = 1;
|
||||
}
|
||||
|
||||
if (n == 1) {
|
||||
// qDebug() << "closeSubpath";
|
||||
GLYPH2PATH_DEBUG() << " closeSubpath";
|
||||
path->closeSubpath();
|
||||
} else {
|
||||
c[3] = start;
|
||||
|
|
@ -524,7 +536,7 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
|
|||
c[2] = (2*c[1] + c[3])/3;
|
||||
c[1] = (2*c[1] + c[0])/3;
|
||||
}
|
||||
// qDebug() << "cubicTo" << c[1] << c[2] << c[3];
|
||||
GLYPH2PATH_DEBUG() << " close cubicTo" << c[1] << c[2] << c[3];
|
||||
path->cubicTo(c[1], c[2], c[3]);
|
||||
}
|
||||
++i;
|
||||
|
|
|
|||
|
|
@ -251,6 +251,8 @@ public:
|
|||
|
||||
static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
|
||||
|
||||
virtual bool hasUnreliableGlyphOutline() const;
|
||||
|
||||
enum HintStyle {
|
||||
HintNone,
|
||||
HintLight,
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ QTextCursorPrivate::AdjustResult QTextCursorPrivate::adjustPosition(int position
|
|||
|
||||
void QTextCursorPrivate::setX()
|
||||
{
|
||||
if (priv->isInEditBlock()) {
|
||||
if (priv->isInEditBlock() || priv->inContentsChange) {
|
||||
x = -1; // mark dirty
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2057,7 +2057,7 @@ void QTextEngine::justify(const QScriptLine &line)
|
|||
// subtract one char more, as we can't justfy after the last character
|
||||
--line_length;
|
||||
|
||||
if (!line_length)
|
||||
if (line_length <= 0)
|
||||
return;
|
||||
|
||||
int firstItem = findItem(line.from);
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ static QByteArray qt_prettyDebug(const char *data, int len, int maxLength)
|
|||
{
|
||||
if (!data) return "(null)";
|
||||
QByteArray out;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
for (int i = 0; i < qMin(len, maxLength); ++i) {
|
||||
char c = data[i];
|
||||
if (isprint(int(uchar(c)))) {
|
||||
out += c;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen)
|
|||
m_vertexCoordEntry(0),
|
||||
m_textureCoordEntry(0),
|
||||
m_textureEntry(0),
|
||||
m_deviceListener(0)
|
||||
m_deviceListener(0),
|
||||
m_updater(screen)
|
||||
{
|
||||
QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
|
||||
if (!hideCursorVal.isEmpty())
|
||||
|
|
@ -270,10 +271,30 @@ bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor)
|
|||
}
|
||||
#endif
|
||||
|
||||
void QEGLPlatformCursorUpdater::update(const QPoint &pos, const QRegion &rgn)
|
||||
{
|
||||
m_active = false;
|
||||
QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(pos), rgn);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
}
|
||||
|
||||
void QEGLPlatformCursorUpdater::scheduleUpdate(const QPoint &pos, const QRegion &rgn)
|
||||
{
|
||||
if (m_active)
|
||||
return;
|
||||
|
||||
m_active = true;
|
||||
|
||||
// Must not flush the window system events directly from here since we are likely to
|
||||
// be a called directly from QGuiApplication's processMouseEvents. Flushing events
|
||||
// could cause reentering by dispatching more queued mouse events.
|
||||
QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection,
|
||||
Q_ARG(QPoint, pos), Q_ARG(QRegion, rgn));
|
||||
}
|
||||
|
||||
void QEGLPlatformCursor::update(const QRegion &rgn)
|
||||
{
|
||||
QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(m_cursor.pos), rgn);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
m_updater.scheduleUpdate(m_cursor.pos, rgn);
|
||||
}
|
||||
|
||||
QRect QEGLPlatformCursor::cursorRect() const
|
||||
|
|
|
|||
|
|
@ -68,6 +68,24 @@ private:
|
|||
int m_mouseCount;
|
||||
};
|
||||
|
||||
class QEGLPlatformCursorUpdater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QEGLPlatformCursorUpdater(QPlatformScreen *screen)
|
||||
: m_screen(screen), m_active(false) { }
|
||||
|
||||
void scheduleUpdate(const QPoint &pos, const QRegion &rgn);
|
||||
|
||||
private slots:
|
||||
void update(const QPoint &pos, const QRegion &rgn);
|
||||
|
||||
private:
|
||||
QPlatformScreen *m_screen;
|
||||
bool m_active;
|
||||
};
|
||||
|
||||
class QEGLPlatformCursor : public QPlatformCursor
|
||||
{
|
||||
public:
|
||||
|
|
@ -130,6 +148,7 @@ private:
|
|||
int m_textureCoordEntry;
|
||||
int m_textureEntry;
|
||||
QEGLPlatformCursorDeviceListener *m_deviceListener;
|
||||
QEGLPlatformCursorUpdater m_updater;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
#include "qdebug.h"
|
||||
|
||||
static const char m_qtTag[] = "QtA11y";
|
||||
static const char m_qtTag[] = "Qt A11Y";
|
||||
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
|
||||
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
|
||||
|
||||
|
|
@ -184,8 +184,6 @@ if (!clazz) { \
|
|||
desc = iface->text(QAccessible::Name);
|
||||
if (desc.isEmpty())
|
||||
desc = iface->text(QAccessible::Description);
|
||||
|
||||
desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role()));
|
||||
}
|
||||
|
||||
jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
|
||||
|
|
@ -216,12 +214,6 @@ if (!clazz) { \
|
|||
}
|
||||
}
|
||||
|
||||
if ((iface->role() != QAccessible::NoRole) &&
|
||||
(iface->role() != QAccessible::Client) &&
|
||||
(iface->role() != QAccessible::Pane)) {
|
||||
desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role()));
|
||||
}
|
||||
|
||||
CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled)
|
||||
//CALL_METHOD(node, "setFocusable", "(Z)V", state.focusable)
|
||||
CALL_METHOD(node, "setFocusable", "(Z)V", true)
|
||||
|
|
|
|||
|
|
@ -769,7 +769,6 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|
|||
|| !QtAndroidInput::registerNatives(env)
|
||||
|| !QtAndroidClipboard::registerNatives(env)
|
||||
|| !QtAndroidMenu::registerNatives(env)
|
||||
|| !QtAndroidAccessibility::registerNatives(env)
|
||||
|| !QtAndroidDialogHelpers::registerNatives(env)) {
|
||||
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -591,19 +591,37 @@ jboolean QAndroidInputContext::endBatchEdit()
|
|||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/)
|
||||
/*
|
||||
Android docs say: If composing, replace compose text with \a text.
|
||||
Otherwise insert \a text at current cursor position.
|
||||
|
||||
The cursor should then be moved to newCursorPosition. If > 0, this is
|
||||
relative to the end of the text - 1; if <= 0, this is relative to the start
|
||||
of the text. updateSelection() needs to be called.
|
||||
*/
|
||||
jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPosition)
|
||||
{
|
||||
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
|
||||
if (query.isNull())
|
||||
return JNI_FALSE;
|
||||
QInputMethodEvent event;
|
||||
event.setCommitString(text);
|
||||
sendInputMethodEvent(&event);
|
||||
clear();
|
||||
|
||||
// Qt has now put the cursor at the end of the text, corresponding to newCursorPosition == 1
|
||||
if (newCursorPosition != 1) {
|
||||
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
|
||||
if (!query.isNull()) {
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
const int localPos = query->value(Qt::ImCursorPosition).toInt();
|
||||
const int newLocalPos = newCursorPosition > 0
|
||||
? localPos + newCursorPosition - 1
|
||||
: localPos - text.length() + newCursorPosition;
|
||||
//move the cursor
|
||||
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
|
||||
newLocalPos, 0, QVariant()));
|
||||
}
|
||||
}
|
||||
|
||||
const int cursorPos = getAbsoluteCursorPosition(query);
|
||||
m_composingText = text;
|
||||
m_composingTextStart = cursorPos;
|
||||
m_composingCursor = cursorPos + text.length();
|
||||
finishComposingText();
|
||||
//### move cursor to newCursorPosition and call updateCursorPosition()
|
||||
updateCursorPosition();
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -624,9 +642,24 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right
|
|||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
// Android docs say the cursor must not move
|
||||
jboolean QAndroidInputContext::finishComposingText()
|
||||
{
|
||||
QInputMethodEvent event;
|
||||
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
|
||||
if (query.isNull())
|
||||
return JNI_FALSE;
|
||||
|
||||
if (m_composingText.isEmpty())
|
||||
return JNI_TRUE; // not composing
|
||||
|
||||
const int blockPos = getBlockPosition(query);
|
||||
const int localCursorPos = m_composingCursor - blockPos;
|
||||
|
||||
// Moving Qt's cursor to where the preedit cursor used to be
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, localCursorPos, 0, QVariant()));
|
||||
|
||||
QInputMethodEvent event(QString(), attributes);
|
||||
event.setCommitString(m_composingText);
|
||||
sendInputMethodEvent(&event);
|
||||
clear();
|
||||
|
|
|
|||
|
|
@ -92,16 +92,20 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
|
|||
QFont newFont;
|
||||
if (cocoaFont) {
|
||||
int pSize = qRound([cocoaFont pointSize]);
|
||||
CTFontDescriptorRef font = CTFontCopyFontDescriptor((CTFontRef)cocoaFont);
|
||||
// QCoreTextFontDatabase::populateFontDatabase() is using localized names
|
||||
QString family = QCFString::toQString((CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL));
|
||||
QString style = QCFString::toQString((CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL));
|
||||
QString family(QCFString::toQString([cocoaFont familyName]));
|
||||
QString typeface(QCFString::toQString([cocoaFont fontName]));
|
||||
|
||||
newFont = QFontDatabase().font(family, style, pSize);
|
||||
int hyphenPos = typeface.indexOf(QLatin1Char('-'));
|
||||
if (hyphenPos != -1) {
|
||||
typeface.remove(0, hyphenPos + 1);
|
||||
} else {
|
||||
typeface = QLatin1String("Normal");
|
||||
}
|
||||
|
||||
newFont = QFontDatabase().font(family, typeface, pSize);
|
||||
newFont.setUnderline(resolveFont.underline());
|
||||
newFont.setStrikeOut(resolveFont.strikeOut());
|
||||
|
||||
CFRelease(font);
|
||||
}
|
||||
return newFont;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,6 +234,10 @@ QCocoaMenu::QCocoaMenu() :
|
|||
|
||||
QCocoaMenu::~QCocoaMenu()
|
||||
{
|
||||
foreach (QCocoaMenuItem *item, m_menuItems) {
|
||||
if (COCOA_MENU_ANCESTOR(item) == this)
|
||||
SET_COCOA_MENU_ANCESTOR(item, 0);
|
||||
}
|
||||
QCocoaAutoReleasePool pool;
|
||||
[m_nativeItem setSubmenu:nil];
|
||||
[m_nativeMenu release];
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ QCocoaMenuItem::QCocoaMenuItem() :
|
|||
|
||||
QCocoaMenuItem::~QCocoaMenuItem()
|
||||
{
|
||||
if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this)
|
||||
SET_COCOA_MENU_ANCESTOR(m_menu, 0);
|
||||
if (m_merged) {
|
||||
[m_native setHidden:YES];
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -463,7 +463,11 @@ bool QCocoaPrintDevice::openPpdFile()
|
|||
ppdClose(m_ppd);
|
||||
m_ppd = 0;
|
||||
CFURLRef ppdURL = NULL;
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
|
||||
char ppdPath[PATH_MAX];
|
||||
#else
|
||||
char ppdPath[MAXPATHLEN];
|
||||
#endif
|
||||
if (PMPrinterCopyDescriptionURL(m_printer, kPMPPDDescriptionType, &ppdURL) == noErr
|
||||
&& ppdURL != NULL
|
||||
&& CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath))) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ QT *= core-private
|
|||
QT *= gui-private
|
||||
QT *= platformsupport-private
|
||||
|
||||
LIBS *= -ld2d1 -ld3d11 -ldwrite
|
||||
LIBS *= -ld2d1 -ld3d11 -ldwrite -lVersion
|
||||
|
||||
include(../windows/windows.pri)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
|
|
@ -66,6 +66,16 @@ static inline QWindowsDirect2DPlatformPixmap *platformPixmap(QPixmap *p)
|
|||
return static_cast<QWindowsDirect2DPlatformPixmap *>(p->handle());
|
||||
}
|
||||
|
||||
static inline QWindowsDirect2DBitmap *bitmap(QPixmap *p)
|
||||
{
|
||||
return platformPixmap(p)->bitmap();
|
||||
}
|
||||
|
||||
static inline QWindowsDirect2DWindow *nativeWindow(QWindow *window)
|
||||
{
|
||||
return static_cast<QWindowsDirect2DWindow *>(window->handle());
|
||||
}
|
||||
|
||||
QWindowsDirect2DBackingStore::QWindowsDirect2DBackingStore(QWindow *window)
|
||||
: QPlatformBackingStore(window)
|
||||
{
|
||||
|
|
@ -77,36 +87,40 @@ QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore()
|
|||
|
||||
void QWindowsDirect2DBackingStore::beginPaint(const QRegion &)
|
||||
{
|
||||
platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->begin();
|
||||
bitmap(nativeWindow(window())->pixmap())->deviceContext()->begin();
|
||||
}
|
||||
|
||||
void QWindowsDirect2DBackingStore::endPaint()
|
||||
{
|
||||
platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->end();
|
||||
bitmap(nativeWindow(window())->pixmap())->deviceContext()->end();
|
||||
}
|
||||
|
||||
QPaintDevice *QWindowsDirect2DBackingStore::paintDevice()
|
||||
{
|
||||
return m_pixmap.data();
|
||||
return nativeWindow(window())->pixmap();
|
||||
}
|
||||
|
||||
void QWindowsDirect2DBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||
void QWindowsDirect2DBackingStore::flush(QWindow *targetWindow, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
QPlatformWindow *pw = window->handle();
|
||||
if (pw && m_pixmap)
|
||||
static_cast<QWindowsDirect2DWindow *>(pw)->flush(platformPixmap(m_pixmap.data())->bitmap(), region, offset);
|
||||
if (targetWindow != window()) {
|
||||
QSharedPointer<QWindowsDirect2DBitmap> copy(nativeWindow(window())->copyBackBuffer());
|
||||
nativeWindow(targetWindow)->flush(copy.data(), region, offset);
|
||||
}
|
||||
|
||||
nativeWindow(targetWindow)->present();
|
||||
}
|
||||
|
||||
void QWindowsDirect2DBackingStore::resize(const QSize &size, const QRegion ®ion)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
QPixmap old = nativeWindow(window())->pixmap()->copy();
|
||||
|
||||
QScopedPointer<QPixmap> oldPixmap(m_pixmap.take());
|
||||
m_pixmap.reset(new QPixmap(size.width(), size.height()));
|
||||
nativeWindow(window())->resizeSwapChain(size);
|
||||
QPixmap *newPixmap = nativeWindow(window())->pixmap();
|
||||
|
||||
if (oldPixmap) {
|
||||
foreach (const QRect &rect, region.rects())
|
||||
platformPixmap(m_pixmap.data())->copy(oldPixmap->handle(), rect);
|
||||
if (!old.isNull()) {
|
||||
foreach (const QRect &rect, region.rects()) {
|
||||
platformPixmap(newPixmap)->copy(old.handle(), rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWindowsDirect2DWindow;
|
||||
|
||||
class QWindowsDirect2DBackingStore : public QPlatformBackingStore
|
||||
{
|
||||
Q_DISABLE_COPY(QWindowsDirect2DBackingStore)
|
||||
|
|
@ -62,11 +64,8 @@ public:
|
|||
void endPaint();
|
||||
|
||||
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
|
||||
void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE;
|
||||
void flush(QWindow *targetWindow, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE;
|
||||
void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QScopedPointer<QPixmap> m_pixmap;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter));
|
||||
hr = dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@
|
|||
|
||||
#include "qwindowscontext.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <qplatformdefs.h>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtGui/private/qpixmap_raster_p.h>
|
||||
#include <QtGui/qpa/qwindowsysteminterface.h>
|
||||
|
||||
|
|
@ -61,8 +62,140 @@ public:
|
|||
QWindowsDirect2DContext m_d2dContext;
|
||||
};
|
||||
|
||||
class Direct2DVersion
|
||||
{
|
||||
private:
|
||||
Direct2DVersion()
|
||||
: partOne(0)
|
||||
, partTwo(0)
|
||||
, partThree(0)
|
||||
, partFour(0)
|
||||
{}
|
||||
|
||||
Direct2DVersion(int one, int two, int three, int four)
|
||||
: partOne(one)
|
||||
, partTwo(two)
|
||||
, partThree(three)
|
||||
, partFour(four)
|
||||
{}
|
||||
|
||||
public:
|
||||
// 6.2.9200.16765 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update
|
||||
enum {
|
||||
D2DMinVersionPart1 = 6,
|
||||
D2DMinVersionPart2 = 2,
|
||||
D2DMinVersionPart3 = 9200,
|
||||
D2DMinVersionPart4 = 16765
|
||||
};
|
||||
|
||||
static Direct2DVersion systemVersion() {
|
||||
static const int bufSize = 512;
|
||||
TCHAR filename[bufSize];
|
||||
|
||||
UINT i = GetSystemDirectory(filename, bufSize);
|
||||
if (i > 0 && i < MAX_PATH) {
|
||||
if (_tcscat_s(filename, MAX_PATH, __TEXT("\\d2d1.dll")) == 0) {
|
||||
DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL);
|
||||
if (versionInfoSize) {
|
||||
QVector<BYTE> info(versionInfoSize);
|
||||
if (GetFileVersionInfo(filename, NULL, versionInfoSize, info.data())) {
|
||||
UINT size;
|
||||
DWORD *fi;
|
||||
|
||||
if (VerQueryValue(info.constData(), __TEXT("\\"), (LPVOID *) &fi, &size) && size) {
|
||||
VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *) fi;
|
||||
return Direct2DVersion(HIWORD(verInfo->dwFileVersionMS),
|
||||
LOWORD(verInfo->dwFileVersionMS),
|
||||
HIWORD(verInfo->dwFileVersionLS),
|
||||
LOWORD(verInfo->dwFileVersionLS));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Direct2DVersion();
|
||||
}
|
||||
|
||||
static Direct2DVersion minimumVersion() {
|
||||
return Direct2DVersion(D2DMinVersionPart1,
|
||||
D2DMinVersionPart2,
|
||||
D2DMinVersionPart3,
|
||||
D2DMinVersionPart4);
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return partOne || partTwo || partThree || partFour;
|
||||
}
|
||||
|
||||
bool operator<(const Direct2DVersion &other) {
|
||||
int c = cmp(partOne, other.partOne);
|
||||
if (c > 0)
|
||||
return false;
|
||||
if (c < 0)
|
||||
return true;
|
||||
|
||||
c = cmp(partTwo, other.partTwo);
|
||||
if (c > 0)
|
||||
return false;
|
||||
if (c < 0)
|
||||
return true;
|
||||
|
||||
c = cmp(partThree, other.partThree);
|
||||
if (c > 0)
|
||||
return false;
|
||||
if (c < 0)
|
||||
return true;
|
||||
|
||||
c = cmp(partFour, other.partFour);
|
||||
if (c > 0)
|
||||
return false;
|
||||
if (c < 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static Q_DECL_CONSTEXPR int cmp(int a, int b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
int partOne, partTwo, partThree, partFour;
|
||||
};
|
||||
|
||||
QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList ¶mList)
|
||||
{
|
||||
Direct2DVersion systemVersion = Direct2DVersion::systemVersion();
|
||||
|
||||
if (systemVersion.isValid() && systemVersion < Direct2DVersion::minimumVersion()) {
|
||||
QString msg = QCoreApplication::translate("QWindowsDirect2DIntegration",
|
||||
"Qt cannot load the direct2d platform plugin because " \
|
||||
"the Direct2D version on this system is too old. The " \
|
||||
"minimum system requirement for this platform plugin " \
|
||||
"is Windows 7 SP1 with Platform Update.\n\n" \
|
||||
"The minimum Direct2D version required is %1.%2.%3.%4. " \
|
||||
"The Direct2D version on this system is %5.%6.%7.%8.");
|
||||
|
||||
msg = msg.arg(Direct2DVersion::D2DMinVersionPart1)
|
||||
.arg(Direct2DVersion::D2DMinVersionPart2)
|
||||
.arg(Direct2DVersion::D2DMinVersionPart3)
|
||||
.arg(Direct2DVersion::D2DMinVersionPart4)
|
||||
.arg(systemVersion.partOne)
|
||||
.arg(systemVersion.partTwo)
|
||||
.arg(systemVersion.partThree)
|
||||
.arg(systemVersion.partFour);
|
||||
|
||||
QString caption = QCoreApplication::translate("QWindowsDirect2DIntegration",
|
||||
"Cannot load direct2d platform plugin");
|
||||
|
||||
MessageBoxW(NULL,
|
||||
msg.toStdWString().c_str(),
|
||||
caption.toStdWString().c_str(),
|
||||
MB_OK | MB_ICONERROR);
|
||||
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
|
||||
QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList);
|
||||
|
||||
if (!integration->init()) {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@
|
|||
#include <QtGui/private/qfontengine_p.h>
|
||||
#include <QtGui/private/qstatictext_p.h>
|
||||
|
||||
#include <wrl.h>
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -346,6 +345,8 @@ public:
|
|||
|
||||
QPointF currentBrushOrigin;
|
||||
|
||||
QHash< QFont, ComPtr<IDWriteFontFace> > fontCache;
|
||||
|
||||
struct {
|
||||
bool emulate;
|
||||
QPen qpen;
|
||||
|
|
@ -1291,44 +1292,6 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
|
|||
}
|
||||
}
|
||||
|
||||
static ComPtr<IDWriteFontFace> fontFaceFromFontEngine(QFontEngine *fe)
|
||||
{
|
||||
ComPtr<IDWriteFontFace> fontFace;
|
||||
|
||||
switch (fe->type()) {
|
||||
case QFontEngine::Win:
|
||||
{
|
||||
QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe);
|
||||
QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
|
||||
|
||||
HGDIOBJ oldfont = wfe->selectDesignFont();
|
||||
HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
|
||||
DeleteObject(SelectObject(wfed->hdc, oldfont));
|
||||
if (FAILED(hr))
|
||||
qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef QT_NO_DIRECTWRITE
|
||||
|
||||
case QFontEngine::DirectWrite:
|
||||
{
|
||||
QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(fe);
|
||||
fontFace = wfedw->directWriteFontFace();
|
||||
}
|
||||
break;
|
||||
|
||||
#endif // QT_NO_DIRECTWRITE
|
||||
|
||||
default:
|
||||
qWarning("%s: Unknown font engine!", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
return fontFace;
|
||||
}
|
||||
|
||||
void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticTextItem)
|
||||
{
|
||||
Q_D(QWindowsDirect2DPaintEngine);
|
||||
|
|
@ -1340,24 +1303,22 @@ void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticText
|
|||
ensurePen();
|
||||
|
||||
// If we can't support the current configuration with Direct2D, fall back to slow path
|
||||
// Most common cases are perspective transform and gradient brush as pen
|
||||
if ((state()->transform().isAffine() == false) || d->pen.emulate) {
|
||||
if (emulationRequired(PenEmulation)) {
|
||||
QPaintEngineEx::drawStaticTextItem(staticTextItem);
|
||||
return;
|
||||
}
|
||||
|
||||
ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->fontEngine());
|
||||
ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->font, staticTextItem->fontEngine());
|
||||
if (!fontFace) {
|
||||
qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
|
||||
QPaintEngineEx::drawStaticTextItem(staticTextItem);
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<UINT16> glyphIndices(staticTextItem->numGlyphs);
|
||||
QVector<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
|
||||
QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
|
||||
QVarLengthArray<UINT16> glyphIndices(staticTextItem->numGlyphs);
|
||||
QVarLengthArray<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
|
||||
QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
|
||||
|
||||
// XXX Are we generating a lot of cache misses here?
|
||||
for (int i = 0; i < staticTextItem->numGlyphs; i++) {
|
||||
glyphIndices[i] = UINT16(staticTextItem->glyphs[i]); // Imperfect conversion here
|
||||
|
||||
|
|
@ -1390,24 +1351,22 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem
|
|||
ensurePen();
|
||||
|
||||
// If we can't support the current configuration with Direct2D, fall back to slow path
|
||||
// Most common cases are perspective transform and gradient brush as pen
|
||||
if ((state()->transform().isAffine() == false) || d->pen.emulate) {
|
||||
if (emulationRequired(PenEmulation)) {
|
||||
QPaintEngine::drawTextItem(p, textItem);
|
||||
return;
|
||||
}
|
||||
|
||||
ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(ti.fontEngine);
|
||||
ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(*ti.f, ti.fontEngine);
|
||||
if (!fontFace) {
|
||||
qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
|
||||
QPaintEngine::drawTextItem(p, textItem);
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<UINT16> glyphIndices(ti.glyphs.numGlyphs);
|
||||
QVector<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
|
||||
QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
|
||||
QVarLengthArray<UINT16> glyphIndices(ti.glyphs.numGlyphs);
|
||||
QVarLengthArray<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
|
||||
QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
|
||||
|
||||
// XXX Are we generating a lot of cache misses here?
|
||||
for (int i = 0; i < ti.glyphs.numGlyphs; i++) {
|
||||
glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]); // Imperfect conversion here
|
||||
glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal();
|
||||
|
|
@ -1618,4 +1577,49 @@ void QWindowsDirect2DPaintEngine::adjustForAliasing(QPointF *point)
|
|||
(*point) += adjustment;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace> QWindowsDirect2DPaintEngine::fontFaceFromFontEngine(const QFont &font, QFontEngine *fe)
|
||||
{
|
||||
Q_D(QWindowsDirect2DPaintEngine);
|
||||
|
||||
ComPtr<IDWriteFontFace> fontFace = d->fontCache.value(font);
|
||||
if (fontFace)
|
||||
return fontFace;
|
||||
|
||||
switch (fe->type()) {
|
||||
case QFontEngine::Win:
|
||||
{
|
||||
QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe);
|
||||
QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
|
||||
|
||||
HGDIOBJ oldfont = wfe->selectDesignFont();
|
||||
HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
|
||||
DeleteObject(SelectObject(wfed->hdc, oldfont));
|
||||
if (FAILED(hr))
|
||||
qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef QT_NO_DIRECTWRITE
|
||||
|
||||
case QFontEngine::DirectWrite:
|
||||
{
|
||||
QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(fe);
|
||||
fontFace = wfedw->directWriteFontFace();
|
||||
}
|
||||
break;
|
||||
|
||||
#endif // QT_NO_DIRECTWRITE
|
||||
|
||||
default:
|
||||
qWarning("%s: Unknown font engine!", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fontFace)
|
||||
d->fontCache.insert(font, fontFace);
|
||||
|
||||
return fontFace;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include <d2d1_1.h>
|
||||
#include <dwrite_1.h>
|
||||
#include <wrl.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -114,6 +115,8 @@ private:
|
|||
bool antiAliasingEnabled() const;
|
||||
void adjustForAliasing(QRectF *rect);
|
||||
void adjustForAliasing(QPointF *point);
|
||||
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace> fontFaceFromFontEngine(const QFont &font, QFontEngine *fe);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
|
|
@ -56,12 +56,27 @@ class QWindowsDirect2DPlatformPixmapPrivate
|
|||
{
|
||||
public:
|
||||
QWindowsDirect2DPlatformPixmapPrivate()
|
||||
: bitmap(new QWindowsDirect2DBitmap)
|
||||
, device(new QWindowsDirect2DPaintDevice(bitmap.data(), QInternal::Pixmap))
|
||||
: owns_bitmap(true)
|
||||
, bitmap(new QWindowsDirect2DBitmap)
|
||||
, device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap))
|
||||
, devicePixelRatio(1.0)
|
||||
{}
|
||||
|
||||
QScopedPointer<QWindowsDirect2DBitmap> bitmap;
|
||||
QWindowsDirect2DPlatformPixmapPrivate(QWindowsDirect2DBitmap *bitmap)
|
||||
: owns_bitmap(false)
|
||||
, bitmap(bitmap)
|
||||
, device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap))
|
||||
, devicePixelRatio(1.0)
|
||||
{}
|
||||
|
||||
~QWindowsDirect2DPlatformPixmapPrivate()
|
||||
{
|
||||
if (owns_bitmap)
|
||||
delete bitmap;
|
||||
}
|
||||
|
||||
bool owns_bitmap;
|
||||
QWindowsDirect2DBitmap *bitmap;
|
||||
QScopedPointer<QWindowsDirect2DPaintDevice> device;
|
||||
qreal devicePixelRatio;
|
||||
};
|
||||
|
|
@ -75,6 +90,19 @@ QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(PixelType pixelTy
|
|||
setSerialNumber(qt_d2dpixmap_serno++);
|
||||
}
|
||||
|
||||
QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixelType pixelType,
|
||||
QWindowsDirect2DBitmap *bitmap)
|
||||
: QPlatformPixmap(pixelType, Direct2DClass)
|
||||
, d_ptr(new QWindowsDirect2DPlatformPixmapPrivate(bitmap))
|
||||
{
|
||||
setSerialNumber(qt_d2dpixmap_serno++);
|
||||
|
||||
is_null = false;
|
||||
w = bitmap->size().width();
|
||||
h = bitmap->size().height();
|
||||
this->d = 32;
|
||||
}
|
||||
|
||||
QWindowsDirect2DPlatformPixmap::~QWindowsDirect2DPlatformPixmap()
|
||||
{
|
||||
|
||||
|
|
@ -173,7 +201,7 @@ void QWindowsDirect2DPlatformPixmap::setDevicePixelRatio(qreal scaleFactor)
|
|||
QWindowsDirect2DBitmap *QWindowsDirect2DPlatformPixmap::bitmap() const
|
||||
{
|
||||
Q_D(const QWindowsDirect2DPlatformPixmap);
|
||||
return d->bitmap.data();
|
||||
return d->bitmap;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
|
|
@ -55,6 +55,9 @@ class QWindowsDirect2DPlatformPixmap : public QPlatformPixmap
|
|||
Q_DECLARE_PRIVATE(QWindowsDirect2DPlatformPixmap)
|
||||
public:
|
||||
QWindowsDirect2DPlatformPixmap(PixelType pixelType);
|
||||
|
||||
// We do NOT take ownership of the bitmap through this constructor!
|
||||
QWindowsDirect2DPlatformPixmap(PixelType pixelType, QWindowsDirect2DBitmap *bitmap);
|
||||
~QWindowsDirect2DPlatformPixmap();
|
||||
|
||||
virtual void resize(int width, int height);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "qwindowsdirect2dwindow.h"
|
||||
#include "qwindowsdirect2ddevicecontext.h"
|
||||
#include "qwindowsdirect2dhelpers.h"
|
||||
#include "qwindowsdirect2dplatformpixmap.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <d2d1_1.h>
|
||||
|
|
@ -87,6 +88,13 @@ QWindowsDirect2DWindow::~QWindowsDirect2DWindow()
|
|||
{
|
||||
}
|
||||
|
||||
QPixmap *QWindowsDirect2DWindow::pixmap()
|
||||
{
|
||||
setupBitmap();
|
||||
|
||||
return m_pixmap.data();
|
||||
}
|
||||
|
||||
void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC1 desc;
|
||||
|
|
@ -102,32 +110,38 @@ void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion
|
|||
if (!m_bitmap)
|
||||
return;
|
||||
|
||||
m_bitmap->deviceContext()->begin();
|
||||
if (bitmap != m_bitmap.data()) {
|
||||
m_bitmap->deviceContext()->begin();
|
||||
|
||||
ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get();
|
||||
if (!m_needsFullFlush) {
|
||||
QRegion clipped = region;
|
||||
clipped &= QRect(0, 0, desc.Width, desc.Height);
|
||||
ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get();
|
||||
if (!m_needsFullFlush) {
|
||||
QRegion clipped = region;
|
||||
clipped &= QRect(0, 0, desc.Width, desc.Height);
|
||||
|
||||
foreach (const QRect &rect, clipped.rects()) {
|
||||
QRectF rectF(rect);
|
||||
foreach (const QRect &rect, clipped.rects()) {
|
||||
QRectF rectF(rect);
|
||||
dc->DrawBitmap(bitmap->bitmap(),
|
||||
to_d2d_rect_f(rectF),
|
||||
1.0,
|
||||
D2D1_INTERPOLATION_MODE_LINEAR,
|
||||
to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
|
||||
}
|
||||
} else {
|
||||
QRectF rectF(0, 0, desc.Width, desc.Height);
|
||||
dc->DrawBitmap(bitmap->bitmap(),
|
||||
to_d2d_rect_f(rectF),
|
||||
1.0,
|
||||
D2D1_INTERPOLATION_MODE_LINEAR,
|
||||
to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
|
||||
m_needsFullFlush = false;
|
||||
}
|
||||
} else {
|
||||
QRectF rectF(0, 0, desc.Width, desc.Height);
|
||||
dc->DrawBitmap(bitmap->bitmap(),
|
||||
to_d2d_rect_f(rectF),
|
||||
1.0,
|
||||
D2D1_INTERPOLATION_MODE_LINEAR,
|
||||
to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
|
||||
m_needsFullFlush = false;
|
||||
}
|
||||
|
||||
m_bitmap->deviceContext()->end();
|
||||
m_bitmap->deviceContext()->end();
|
||||
}
|
||||
}
|
||||
|
||||
void QWindowsDirect2DWindow::present()
|
||||
{
|
||||
m_swapChain->Present(0, 0);
|
||||
}
|
||||
|
||||
|
|
@ -136,6 +150,7 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
|
|||
if (!m_swapChain)
|
||||
return;
|
||||
|
||||
m_pixmap.reset();
|
||||
m_bitmap.reset();
|
||||
m_deviceContext->SetTarget(Q_NULLPTR);
|
||||
|
||||
|
|
@ -149,6 +164,43 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
|
|||
m_needsFullFlush = true;
|
||||
}
|
||||
|
||||
QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() const
|
||||
{
|
||||
const QSharedPointer<QWindowsDirect2DBitmap> null_result;
|
||||
|
||||
if (!m_bitmap)
|
||||
return null_result;
|
||||
|
||||
D2D1_PIXEL_FORMAT format = m_bitmap->bitmap()->GetPixelFormat();
|
||||
D2D1_SIZE_U size = m_bitmap->bitmap()->GetPixelSize();
|
||||
|
||||
FLOAT dpiX, dpiY;
|
||||
m_bitmap->bitmap()->GetDpi(&dpiX, &dpiY);
|
||||
|
||||
D2D1_BITMAP_PROPERTIES1 properties = {
|
||||
format, // D2D1_PIXEL_FORMAT pixelFormat;
|
||||
dpiX, // FLOAT dpiX;
|
||||
dpiY, // FLOAT dpiY;
|
||||
D2D1_BITMAP_OPTIONS_TARGET, // D2D1_BITMAP_OPTIONS bitmapOptions;
|
||||
Q_NULLPTR // _Field_size_opt_(1) ID2D1ColorContext *colorContext;
|
||||
};
|
||||
ComPtr<ID2D1Bitmap1> copy;
|
||||
HRESULT hr = m_deviceContext.Get()->CreateBitmap(size, NULL, 0, properties, ©);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
qWarning("%s: Could not create staging bitmap: %#x", __FUNCTION__, hr);
|
||||
return null_result;
|
||||
}
|
||||
|
||||
hr = copy.Get()->CopyFromBitmap(NULL, m_bitmap->bitmap(), NULL);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("%s: Could not copy from bitmap! %#x", __FUNCTION__, hr);
|
||||
return null_result;
|
||||
}
|
||||
|
||||
return QSharedPointer<QWindowsDirect2DBitmap>(new QWindowsDirect2DBitmap(copy.Get(), Q_NULLPTR));
|
||||
}
|
||||
|
||||
void QWindowsDirect2DWindow::setupBitmap()
|
||||
{
|
||||
if (m_bitmap)
|
||||
|
|
@ -175,6 +227,10 @@ void QWindowsDirect2DWindow::setupBitmap()
|
|||
}
|
||||
|
||||
m_bitmap.reset(new QWindowsDirect2DBitmap(backBufferBitmap.Get(), m_deviceContext.Get()));
|
||||
|
||||
QWindowsDirect2DPlatformPixmap *pp = new QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixmapType,
|
||||
m_bitmap.data());
|
||||
m_pixmap.reset(new QPixmap(pp));
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -56,16 +56,21 @@ public:
|
|||
QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data);
|
||||
~QWindowsDirect2DWindow();
|
||||
|
||||
QPixmap *pixmap();
|
||||
void flush(QWindowsDirect2DBitmap *bitmap, const QRegion ®ion, const QPoint &offset);
|
||||
void present();
|
||||
void resizeSwapChain(const QSize &size);
|
||||
|
||||
QSharedPointer<QWindowsDirect2DBitmap> copyBackBuffer() const;
|
||||
|
||||
private:
|
||||
void resizeSwapChain(const QSize &size);
|
||||
void setupBitmap();
|
||||
|
||||
private:
|
||||
Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
|
||||
Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext;
|
||||
QScopedPointer<QWindowsDirect2DBitmap> m_bitmap;
|
||||
QScopedPointer<QPixmap> m_pixmap;
|
||||
bool m_needsFullFlush;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@
|
|||
break;
|
||||
}
|
||||
QWindowSystemInterface::handleApplicationStateChanged(state);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ public:
|
|||
WId winId() const { return WId(m_view); };
|
||||
|
||||
private:
|
||||
void applicationStateChanged(Qt::ApplicationState state);
|
||||
void applyGeometry(const QRect &rect);
|
||||
|
||||
QUIView *m_view;
|
||||
|
|
|
|||
|
|
@ -192,12 +192,25 @@
|
|||
|
||||
- (void)displayLayer:(CALayer *)layer
|
||||
{
|
||||
QSize bounds = fromCGRect(layer.bounds).toRect().size();
|
||||
Q_UNUSED(layer);
|
||||
Q_ASSERT(layer == self.layer);
|
||||
|
||||
Q_ASSERT(m_qioswindow->geometry().size() == bounds);
|
||||
Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible());
|
||||
[self sendUpdatedExposeEvent];
|
||||
}
|
||||
|
||||
- (void)sendUpdatedExposeEvent
|
||||
{
|
||||
QRegion region;
|
||||
|
||||
if (m_qioswindow->isExposed()) {
|
||||
QSize bounds = fromCGRect(self.layer.bounds).toRect().size();
|
||||
|
||||
Q_ASSERT(m_qioswindow->geometry().size() == bounds);
|
||||
Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible());
|
||||
|
||||
region = QRect(QPoint(), bounds);
|
||||
}
|
||||
|
||||
QRegion region = self.hidden ? QRegion() : QRect(QPoint(), bounds);
|
||||
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
}
|
||||
|
|
@ -279,19 +292,33 @@
|
|||
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
if (!touches && m_activeTouches.isEmpty())
|
||||
if (m_activeTouches.isEmpty())
|
||||
return;
|
||||
|
||||
if (!touches) {
|
||||
m_activeTouches.clear();
|
||||
} else {
|
||||
for (UITouch *touch in touches)
|
||||
m_activeTouches.remove(touch);
|
||||
// When four-finger swiping, we get a touchesCancelled callback
|
||||
// which includes all four touch points. The swipe gesture is
|
||||
// then active until all four touches have been released, and
|
||||
// we start getting touchesBegan events again.
|
||||
|
||||
Q_ASSERT_X(m_activeTouches.isEmpty(), Q_FUNC_INFO,
|
||||
"Subset of active touches cancelled by UIKit");
|
||||
}
|
||||
// When five-finger pinching, we also get a touchesCancelled
|
||||
// callback with all five touch points, but the pinch gesture
|
||||
// ends when the second to last finger is released from the
|
||||
// screen. The last finger will not emit any more touch
|
||||
// events, _but_, will contribute to starting another pinch
|
||||
// gesture. That second pinch gesture will _not_ trigger a
|
||||
// touchesCancelled event when starting, but as each finger
|
||||
// is released, and we may get touchesMoved events for the
|
||||
// remaining fingers. [event allTouches] also contains one
|
||||
// less touch point than it should, so this behavior is
|
||||
// likely a bug in the iOS system gesture recognizer, but we
|
||||
// have to take it into account when maintaining the Qt state.
|
||||
// We do this by assuming that there are no cases where a
|
||||
// sub-set of the active touch events are intentionally cancelled.
|
||||
|
||||
if (touches && (static_cast<NSInteger>([touches count]) != m_activeTouches.count()))
|
||||
qWarning("Subset of active touches cancelled by UIKit");
|
||||
|
||||
m_activeTouches.clear();
|
||||
m_nextTouchId = 0;
|
||||
|
||||
NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
|
||||
|
|
@ -334,6 +361,8 @@ QIOSWindow::QIOSWindow(QWindow *window)
|
|||
, m_view([[QUIView alloc] initWithQIOSWindow:this])
|
||||
, m_windowLevel(0)
|
||||
{
|
||||
connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QIOSWindow::applicationStateChanged);
|
||||
|
||||
setParent(QPlatformWindow::parent());
|
||||
|
||||
// Resolve default window geometry in case it was not set before creating the
|
||||
|
|
@ -471,7 +500,8 @@ void QIOSWindow::applyGeometry(const QRect &rect)
|
|||
|
||||
bool QIOSWindow::isExposed() const
|
||||
{
|
||||
return window()->isVisible() && !window()->geometry().isEmpty();
|
||||
return qApp->applicationState() > Qt::ApplicationHidden
|
||||
&& window()->isVisible() && !window()->geometry().isEmpty();
|
||||
}
|
||||
|
||||
void QIOSWindow::setWindowState(Qt::WindowState state)
|
||||
|
|
@ -593,6 +623,12 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio
|
|||
[[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO];
|
||||
}
|
||||
|
||||
void QIOSWindow::applicationStateChanged(Qt::ApplicationState)
|
||||
{
|
||||
if (window()->isExposed() != isExposed())
|
||||
[m_view sendUpdatedExposeEvent];
|
||||
}
|
||||
|
||||
qreal QIOSWindow::devicePixelRatio() const
|
||||
{
|
||||
return m_view.contentScaleFactor;
|
||||
|
|
|
|||
|
|
@ -85,8 +85,7 @@ QKmsDevice::~QKmsDevice()
|
|||
|
||||
void QKmsDevice::createScreens()
|
||||
{
|
||||
drmModeRes *resources = 0;
|
||||
resources = drmModeGetResources(m_fd);
|
||||
drmModeRes *resources = drmModeGetResources(m_fd);
|
||||
if (!resources)
|
||||
qFatal("drmModeGetResources failed");
|
||||
|
||||
|
|
@ -95,7 +94,7 @@ void QKmsDevice::createScreens()
|
|||
drmModeConnector *connector = 0;
|
||||
connector = drmModeGetConnector(m_fd, resources->connectors[i]);
|
||||
if (connector && connector->connection == DRM_MODE_CONNECTED) {
|
||||
m_integration->addScreen(new QKmsScreen(this, connector->connector_id));
|
||||
m_integration->addScreen(new QKmsScreen(this, resources, connector));
|
||||
}
|
||||
drmModeFreeConnector(connector);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,18 +63,18 @@ static drmModeModeInfo builtin_1024x768 = {
|
|||
"1024x768"
|
||||
};
|
||||
|
||||
QKmsScreen::QKmsScreen(QKmsDevice *device, int connectorId)
|
||||
QKmsScreen::QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector)
|
||||
: m_device(device),
|
||||
m_current_bo(0),
|
||||
m_next_bo(0),
|
||||
m_connectorId(connectorId),
|
||||
m_connectorId(connector->connector_id),
|
||||
m_depth(32),
|
||||
m_format(QImage::Format_Invalid),
|
||||
m_eglWindowSurface(EGL_NO_SURFACE),
|
||||
m_modeSet(false)
|
||||
{
|
||||
m_cursor = new QKmsCursor(this);
|
||||
initializeScreenMode();
|
||||
initializeScreenMode(resources, connector);
|
||||
}
|
||||
|
||||
QKmsScreen::~QKmsScreen()
|
||||
|
|
@ -114,14 +114,9 @@ QPlatformCursor *QKmsScreen::cursor() const
|
|||
return m_cursor;
|
||||
}
|
||||
|
||||
void QKmsScreen::initializeScreenMode()
|
||||
void QKmsScreen::initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector)
|
||||
{
|
||||
//Determine optimal mode for screen
|
||||
drmModeRes *resources = drmModeGetResources(m_device->fd());
|
||||
if (!resources)
|
||||
qFatal("drmModeGetResources failed");
|
||||
|
||||
drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId);
|
||||
drmModeModeInfo *mode = 0;
|
||||
for (int i = 0; i < connector->count_modes; ++i) {
|
||||
if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
|
||||
|
|
@ -129,8 +124,12 @@ void QKmsScreen::initializeScreenMode()
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!mode)
|
||||
mode = &builtin_1024x768;
|
||||
if (!mode) {
|
||||
if (connector->count_modes > 0)
|
||||
mode = &connector->modes[0];
|
||||
else
|
||||
mode = &builtin_1024x768;
|
||||
}
|
||||
|
||||
drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
|
||||
if (encoder == 0)
|
||||
|
|
@ -162,8 +161,6 @@ void QKmsScreen::initializeScreenMode()
|
|||
qDebug() << "created gbm surface" << m_gbmSurface << m_mode.hdisplay << m_mode.vdisplay;
|
||||
//Cleanup
|
||||
drmModeFreeEncoder(encoder);
|
||||
drmModeFreeConnector(connector);
|
||||
drmModeFreeResources(resources);
|
||||
}
|
||||
|
||||
QSurfaceFormat QKmsScreen::tweakFormat(const QSurfaceFormat &format)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class QKmsContext;
|
|||
class QKmsScreen : public QPlatformScreen
|
||||
{
|
||||
public:
|
||||
QKmsScreen(QKmsDevice *device, int connectorId);
|
||||
QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector);
|
||||
~QKmsScreen();
|
||||
|
||||
QRect geometry() const;
|
||||
|
|
@ -94,7 +94,7 @@ public:
|
|||
|
||||
private:
|
||||
void performPageFlip();
|
||||
void initializeScreenMode();
|
||||
void initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector);
|
||||
|
||||
QKmsDevice *m_device;
|
||||
gbm_bo *m_current_bo;
|
||||
|
|
|
|||
|
|
@ -145,9 +145,8 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion)
|
|||
<< " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
|
||||
}
|
||||
#endif
|
||||
QImage::Format format = QWindowsNativeImage::systemFormat();
|
||||
if (format == QImage::Format_RGB32 && window()->format().hasAlpha())
|
||||
format = QImage::Format_ARGB32_Premultiplied;
|
||||
const QImage::Format format = window()->format().hasAlpha() ?
|
||||
QImage::Format_ARGB32_Premultiplied : QWindowsNativeImage::systemFormat();
|
||||
|
||||
QWindowsNativeImage *oldwni = m_image.data();
|
||||
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);
|
||||
|
|
|
|||
|
|
@ -169,6 +169,20 @@ bool QWindowsFontEngine::hasCMapTable() const
|
|||
return GetFontData(hdc, MAKE_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR;
|
||||
}
|
||||
|
||||
bool QWindowsFontEngine::hasGlyfTable() const
|
||||
{
|
||||
HDC hdc = m_fontEngineData->hdc;
|
||||
SelectObject(hdc, hfont);
|
||||
return GetFontData(hdc, MAKE_TAG('g', 'l', 'y', 'f'), 0, 0, 0) != GDI_ERROR;
|
||||
}
|
||||
|
||||
bool QWindowsFontEngine::hasEbdtTable() const
|
||||
{
|
||||
HDC hdc = m_fontEngineData->hdc;
|
||||
SelectObject(hdc, hfont);
|
||||
return GetFontData(hdc, MAKE_TAG('E', 'B', 'D', 'T'), 0, 0, 0) != GDI_ERROR;
|
||||
}
|
||||
|
||||
void QWindowsFontEngine::getCMap()
|
||||
{
|
||||
ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable();
|
||||
|
|
@ -308,6 +322,8 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name,
|
|||
userData.insert(QStringLiteral("hFont"), QVariant::fromValue(hfont));
|
||||
userData.insert(QStringLiteral("trueType"), QVariant(bool(ttf)));
|
||||
setUserData(userData);
|
||||
|
||||
hasUnreliableOutline = hasGlyfTable() && hasEbdtTable();
|
||||
}
|
||||
|
||||
QWindowsFontEngine::~QWindowsFontEngine()
|
||||
|
|
@ -662,6 +678,11 @@ void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qre
|
|||
}
|
||||
#endif // Q_CC_MINGW
|
||||
|
||||
bool QWindowsFontEngine::hasUnreliableGlyphOutline() const
|
||||
{
|
||||
return hasUnreliableOutline;
|
||||
}
|
||||
|
||||
qreal QWindowsFontEngine::minLeftBearing() const
|
||||
{
|
||||
if (lbearing == SHRT_MIN)
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@ public:
|
|||
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
|
||||
#endif
|
||||
|
||||
bool hasUnreliableGlyphOutline() const Q_DECL_OVERRIDE;
|
||||
|
||||
int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs) const;
|
||||
void getCMap();
|
||||
|
||||
|
|
@ -136,6 +138,8 @@ private:
|
|||
QImage::Format mask_format);
|
||||
bool hasCFFTable() const;
|
||||
bool hasCMapTable() const;
|
||||
bool hasGlyfTable() const;
|
||||
bool hasEbdtTable() const;
|
||||
|
||||
const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
|
||||
|
||||
|
|
@ -146,6 +150,7 @@ private:
|
|||
uint stockFont : 1;
|
||||
uint ttf : 1;
|
||||
uint hasOutline : 1;
|
||||
uint hasUnreliableOutline : 1;
|
||||
uint cffTable : 1;
|
||||
TEXTMETRIC tm;
|
||||
int lw;
|
||||
|
|
|
|||
|
|
@ -496,6 +496,7 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window)
|
|||
|
||||
// Set initial orientation
|
||||
onOrientationChanged(0);
|
||||
setOrientationUpdateMask(m_nativeOrientation);
|
||||
|
||||
m_displayProperties->add_OrientationChanged(Callback<IDisplayPropertiesEventHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
|
||||
&m_tokens[QEvent::OrientationChange]);
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const
|
|||
return;
|
||||
}
|
||||
m_format = QSurfaceFormat();
|
||||
m_format.setRenderableType(QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL
|
||||
m_format.setRenderableType(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL
|
||||
? QSurfaceFormat::OpenGL : QSurfaceFormat::OpenGLES);
|
||||
updateFormatFromContext(m_format);
|
||||
if (vinfo)
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@
|
|||
# libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image,
|
||||
# libxcb-keysyms, libxcb-icccm, libxcb-renderutil, libxcb-xkb
|
||||
#
|
||||
TEMPLATE = lib
|
||||
TARGET = xcb-static
|
||||
CONFIG += staticlib
|
||||
CONFIG += static
|
||||
load(qt_helper_lib)
|
||||
|
||||
XCB_DIR = ../../../../3rdparty/xcb
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
mac: SUBDIRS += cocoa
|
||||
osx: SUBDIRS += cocoa
|
||||
win32: SUBDIRS += windows
|
||||
unix:!mac:contains(QT_CONFIG, cups): SUBDIRS += cups
|
||||
|
|
|
|||
|
|
@ -448,9 +448,10 @@ bool QSqlTableModel::selectRow(int row)
|
|||
// Look for changed values. Primary key fields are customarily first
|
||||
// and probably change less often than other fields, so start at the end.
|
||||
for (int f = curValues.count() - 1; f >= 0; --f) {
|
||||
if (curValues.value(f) != newValues.value(f))
|
||||
if (curValues.value(f) != newValues.value(f)) {
|
||||
needsAddingToCache = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,11 +201,17 @@ inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual,
|
|||
}
|
||||
for (int i = 0; isOk && i < actualSize; ++i) {
|
||||
if (!(t1.at(i) == t2.at(i))) {
|
||||
char *val1 = toString(t1.at(i));
|
||||
char *val2 = toString(t2.at(i));
|
||||
|
||||
qsnprintf(msg, sizeof(msg), "Compared lists differ at index %d.\n"
|
||||
" Actual (%s): %s\n"
|
||||
" Expected (%s): %s", i, actual, toString(t1.at(i)),
|
||||
expected, toString(t2.at(i)));
|
||||
" Expected (%s): %s", i, actual, val1 ? val1 : "<null>",
|
||||
expected, val2 ? val2 : "<null>");
|
||||
isOk = false;
|
||||
|
||||
delete [] val1;
|
||||
delete [] val2;
|
||||
}
|
||||
}
|
||||
return compare_helper(isOk, msg, 0, 0, actual, expected, file, line);
|
||||
|
|
|
|||
|
|
@ -2863,8 +2863,6 @@ bool QTest::currentTestFailed()
|
|||
void QTest::qSleep(int ms)
|
||||
{
|
||||
QTEST_ASSERT(ms > 0);
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
#if defined(Q_OS_WINRT)
|
||||
WaitForSingleObjectEx(GetCurrentThread(), ms, true);
|
||||
|
|
@ -2874,20 +2872,6 @@ void QTest::qSleep(int ms)
|
|||
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
// Warn if the elapsed time was more than 50% longer or more than 10% shorter than the
|
||||
// requested time.
|
||||
qint64 requested = 1000000 * (qint64)ms;
|
||||
qint64 diff = timer.nsecsElapsed() - requested;
|
||||
#ifndef Q_OS_WIN
|
||||
const qint64 factor = 2; // more than 50% longer
|
||||
#else
|
||||
const qint64 factor = 1; // Windows: 50% is quite common, warn about 100%
|
||||
#endif
|
||||
if (diff * factor > requested || diff * 10 < -requested) {
|
||||
QTestLog::warn(qPrintable(
|
||||
QString::fromLatin1("QTest::qSleep() should have taken %1ns, but actually took %2ns!")
|
||||
.arg(requested).arg(diff + requested)), __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
|
|
|||
|
|
@ -647,10 +647,6 @@ QAccessible::State QAccessibleLineEdit::state() const
|
|||
if (l->hasSelectedText())
|
||||
state.selected = true;
|
||||
|
||||
if (l->contextMenuPolicy() != Qt::NoContextMenu
|
||||
&& l->contextMenuPolicy() != Qt::PreventContextMenu)
|
||||
state.hasPopup = true;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2128,6 +2128,11 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
|
|||
return QString();
|
||||
}
|
||||
|
||||
static inline QUrl dialogResultToUrl(const QString &file)
|
||||
{
|
||||
return file.isEmpty() ? QUrl() : QUrl::fromLocalFile(file);
|
||||
}
|
||||
|
||||
/*!
|
||||
This is a convenience static function that returns an existing file
|
||||
selected by the user. If the user presses Cancel, it returns an
|
||||
|
|
@ -2166,7 +2171,7 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent,
|
|||
Q_UNUSED(supportedSchemes);
|
||||
|
||||
// Falls back to local file
|
||||
return QUrl::fromLocalFile(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
|
||||
return dialogResultToUrl(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2424,7 +2429,7 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent,
|
|||
Q_UNUSED(supportedSchemes);
|
||||
|
||||
// Falls back to local file
|
||||
return QUrl::fromLocalFile(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
|
||||
return dialogResultToUrl(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2532,7 +2537,7 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent,
|
|||
Q_UNUSED(supportedSchemes);
|
||||
|
||||
// Falls back to local file
|
||||
return QUrl::fromLocalFile(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
|
||||
return dialogResultToUrl(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
|
||||
}
|
||||
|
||||
inline static QString _qt_get_directory(const QString &path)
|
||||
|
|
|
|||
|
|
@ -1655,7 +1655,7 @@ void QGraphicsView::invalidateScene(const QRectF &rect, QGraphicsScene::SceneLay
|
|||
|
||||
/*!
|
||||
\property QGraphicsView::interactive
|
||||
\brief whether the view allowed scene interaction.
|
||||
\brief whether the view allows scene interaction.
|
||||
|
||||
If enabled, this view is set to allow scene interaction. Otherwise, this
|
||||
view will not allow interaction, and any mouse or key events are ignored
|
||||
|
|
|
|||
|
|
@ -1631,7 +1631,7 @@ QWidget *QListWidget::itemWidget(QListWidgetItem *item) const
|
|||
/*!
|
||||
\since 4.1
|
||||
|
||||
Sets the \a widget to be displayed in the give \a item.
|
||||
Sets the \a widget to be displayed in the given \a item.
|
||||
|
||||
This function should only be used to display static content in the place of
|
||||
a list widget item. If you want to display custom dynamic content or
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtWidgets module of the Qt Toolkit.
|
||||
|
|
@ -1421,15 +1421,8 @@ void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItem *option, c
|
|||
const int right = (spanning ? header->visualIndex(0) : header->count() - 1 );
|
||||
calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);
|
||||
|
||||
int columnIndex = 0;
|
||||
for (int visualIndex = 0; visualIndex < current.column(); ++visualIndex) {
|
||||
int logicalIndex = header->logicalIndex(visualIndex);
|
||||
if (!header->isSectionHidden(logicalIndex)) {
|
||||
++columnIndex;
|
||||
}
|
||||
}
|
||||
|
||||
option->viewItemPosition = viewItemPosList.at(columnIndex);
|
||||
const int visualIndex = logicalIndices.indexOf(current.column());
|
||||
option->viewItemPosition = viewItemPosList.at(visualIndex);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ void QOpenGLWidget::paintGL()
|
|||
void QOpenGLWidget::updateGL()
|
||||
{
|
||||
Q_D(QOpenGLWidget);
|
||||
if (d->uninitialized)
|
||||
if (d->uninitialized || !d->surface())
|
||||
return;
|
||||
|
||||
makeCurrent();
|
||||
|
|
|
|||
|
|
@ -440,11 +440,13 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
|
|||
if (!win)
|
||||
win = w->nativeParentWidget()->windowHandle();
|
||||
if (win && win->geometry().contains(event->globalPos())) {
|
||||
// Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec()
|
||||
const QPoint localPos = win->mapFromGlobal(event->globalPos());
|
||||
QMouseEvent e(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
|
||||
QGuiApplicationPrivate::setMouseEventSource(&e, QGuiApplicationPrivate::mouseEventSource(event));
|
||||
e.setTimestamp(event->timestamp());
|
||||
QApplication::sendSpontaneousEvent(win, &e);
|
||||
QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
|
||||
e->spont = 1;
|
||||
QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event));
|
||||
e->setTimestamp(event->timestamp());
|
||||
QCoreApplication::postEvent(win, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1677,7 +1677,7 @@ QMacStylePrivate::QMacStylePrivate()
|
|||
if (ptrHIShapeGetBounds == 0) {
|
||||
QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
|
||||
library.setLoadHints(QLibrary::ExportExternalSymbolsHint);
|
||||
ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
|
||||
ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5300,7 +5300,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
|||
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
|
||||
HIThemeButtonDrawInfo bdi;
|
||||
d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
|
||||
if (!tds == kThemeStateInactive)
|
||||
if (tds != kThemeStateInactive)
|
||||
QMacStylePrivate::drawCombobox(qt_hirectForQRect(combo->rect), bdi, p);
|
||||
else
|
||||
d->drawColorlessButton(qt_hirectForQRect(combo->rect), &bdi, p, opt);
|
||||
|
|
|
|||
|
|
@ -2606,6 +2606,9 @@ bool QMdiArea::eventFilter(QObject *object, QEvent *event)
|
|||
return QAbstractScrollArea::eventFilter(object, event);
|
||||
}
|
||||
|
||||
if (subWindow->mdiArea() != this)
|
||||
return QAbstractScrollArea::eventFilter(object, event);
|
||||
|
||||
// QMdiSubWindow events:
|
||||
switch (event->type()) {
|
||||
case QEvent::Move:
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activat
|
|||
QAction *previousAction = currentAction;
|
||||
#endif
|
||||
currentAction = action;
|
||||
if (action) {
|
||||
if (action && action->isEnabled()) {
|
||||
activateAction(action, QAction::Hover);
|
||||
if(popup)
|
||||
popupAction(action, activateFirst);
|
||||
|
|
@ -1038,7 +1038,7 @@ void QMenuBar::mousePressEvent(QMouseEvent *e)
|
|||
d->mouseDown = true;
|
||||
|
||||
QAction *action = d->actionAt(e->pos());
|
||||
if (!action || !d->isVisible(action)) {
|
||||
if (!action || !d->isVisible(action) || !action->isEnabled()) {
|
||||
d->setCurrentAction(0);
|
||||
#ifndef QT_NO_WHATSTHIS
|
||||
if (QWhatsThis::inWhatsThisMode())
|
||||
|
|
|
|||
|
|
@ -438,7 +438,6 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
|
|||
|
||||
QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection()));
|
||||
QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor)));
|
||||
QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, SLOT(_q_contentsChanged(int,int,int)));
|
||||
QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged()));
|
||||
|
||||
// convenience signal forwards
|
||||
|
|
@ -501,6 +500,8 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
|
|||
|
||||
q->ensureCursorVisible();
|
||||
emit q->cursorPositionChanged();
|
||||
|
||||
QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, SLOT(_q_contentsChanged(int,int,int)), Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void QWidgetTextControlPrivate::startDrag()
|
||||
|
|
@ -646,7 +647,8 @@ void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, i
|
|||
{
|
||||
Q_Q(QWidgetTextControl);
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
if (QAccessible::isActive()) {
|
||||
|
||||
if (QAccessible::isActive() && q->parent() && q->parent()->isWidgetType()) {
|
||||
QTextCursor tmp(doc);
|
||||
tmp.setPosition(from);
|
||||
tmp.setPosition(from + charsAdded, QTextCursor::KeepAnchor);
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ private slots:
|
|||
|
||||
void QTBUG28998_linkColor();
|
||||
|
||||
void textCursorUsageWithinContentsChange();
|
||||
|
||||
private:
|
||||
void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
|
||||
|
||||
|
|
@ -3021,5 +3023,50 @@ void tst_QTextDocument::QTBUG28998_linkColor()
|
|||
QCOMPARE(format.foreground(), pal.link());
|
||||
}
|
||||
|
||||
class ContentsChangeHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ContentsChangeHandler(QTextDocument *doc)
|
||||
: verticalMovementX(-1)
|
||||
, doc(doc)
|
||||
{
|
||||
connect(doc, SIGNAL(contentsChange(int,int,int)),
|
||||
this, SLOT(saveModifiedText(int, int, int)));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void saveModifiedText(int from, int /*charsRemoved*/, int charsAdded)
|
||||
{
|
||||
QTextCursor tmp(doc);
|
||||
tmp.setPosition(from);
|
||||
tmp.setPosition(from + charsAdded, QTextCursor::KeepAnchor);
|
||||
text = tmp.selectedText();
|
||||
verticalMovementX = tmp.verticalMovementX();
|
||||
}
|
||||
|
||||
public:
|
||||
QString text;
|
||||
int verticalMovementX;
|
||||
private:
|
||||
QTextDocument *doc;
|
||||
};
|
||||
|
||||
void tst_QTextDocument::textCursorUsageWithinContentsChange()
|
||||
{
|
||||
// force creation of layout
|
||||
doc->documentLayout();
|
||||
|
||||
QTextCursor cursor(doc);
|
||||
cursor.insertText("initial text");
|
||||
|
||||
ContentsChangeHandler handler(doc);
|
||||
|
||||
cursor.insertText("new text");
|
||||
|
||||
QCOMPARE(handler.text, QString("new text"));
|
||||
QCOMPARE(handler.verticalMovementX, -1);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTextDocument)
|
||||
#include "tst_qtextdocument.moc"
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ private slots:
|
|||
void boundingRectForUnsetLineWidth();
|
||||
void boundingRectForSetLineWidth();
|
||||
void glyphLessItems();
|
||||
void justifyTrailingSpaces();
|
||||
|
||||
// QTextLine stuff
|
||||
void setNumColumnsWrapAtWordBoundaryOrAnywhere();
|
||||
|
|
@ -1996,5 +1997,19 @@ void tst_QTextLayout::cursorInNonStopChars()
|
|||
QVERIFY(line.cursorToX(2) == line.cursorToX(3));
|
||||
}
|
||||
|
||||
void tst_QTextLayout::justifyTrailingSpaces()
|
||||
{
|
||||
QTextLayout layout(QStringLiteral(" t"), testFont);
|
||||
layout.setTextOption(QTextOption(Qt::AlignJustify));
|
||||
layout.beginLayout();
|
||||
|
||||
QTextLine line = layout.createLine();
|
||||
line.setLineWidth(5);
|
||||
|
||||
layout.endLayout();
|
||||
|
||||
QVERIFY(qFuzzyIsNull(layout.lineAt(0).cursorToX(0)));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTextLayout)
|
||||
#include "tst_qtextlayout.moc"
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ private slots:
|
|||
void emptyConstructor();
|
||||
void constructor_data();
|
||||
void constructor();
|
||||
void constructor_device();
|
||||
void constructingGarbage();
|
||||
void copyAndAssign_data();
|
||||
void copyAndAssign();
|
||||
|
|
@ -111,6 +112,8 @@ private slots:
|
|||
void verify();
|
||||
void extensions();
|
||||
void threadSafeConstMethods();
|
||||
void version_data();
|
||||
void version();
|
||||
|
||||
// helper for verbose test failure messages
|
||||
QString toString(const QList<QSslError>&);
|
||||
|
|
@ -226,6 +229,47 @@ void tst_QSslCertificate::constructor()
|
|||
QVERIFY(!certificate.isNull());
|
||||
}
|
||||
|
||||
void tst_QSslCertificate::constructor_device()
|
||||
{
|
||||
if (!QSslSocket::supportsSsl())
|
||||
return;
|
||||
|
||||
QFile f(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
|
||||
bool ok = f.open(QIODevice::ReadOnly);
|
||||
QVERIFY(ok);
|
||||
|
||||
QSslCertificate cert(&f);
|
||||
QVERIFY(!cert.isNull());
|
||||
f.close();
|
||||
|
||||
// Check opening a DER as a PEM fails
|
||||
QFile f2(testDataDir + "/certificates/cert.der");
|
||||
ok = f2.open(QIODevice::ReadOnly);
|
||||
QVERIFY(ok);
|
||||
|
||||
QSslCertificate cert2(&f2);
|
||||
QVERIFY(cert2.isNull());
|
||||
f2.close();
|
||||
|
||||
// Check opening a DER as a DER works
|
||||
QFile f3(testDataDir + "/certificates/cert.der");
|
||||
ok = f3.open(QIODevice::ReadOnly);
|
||||
QVERIFY(ok);
|
||||
|
||||
QSslCertificate cert3(&f3, QSsl::Der);
|
||||
QVERIFY(!cert3.isNull());
|
||||
f3.close();
|
||||
|
||||
// Check opening a PEM as a DER fails
|
||||
QFile f4(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
|
||||
ok = f4.open(QIODevice::ReadOnly);
|
||||
QVERIFY(ok);
|
||||
|
||||
QSslCertificate cert4(&f4, QSsl::Der);
|
||||
QVERIFY(cert4.isNull());
|
||||
f4.close();
|
||||
}
|
||||
|
||||
void tst_QSslCertificate::constructingGarbage()
|
||||
{
|
||||
if (!QSslSocket::supportsSsl())
|
||||
|
|
@ -1158,6 +1202,33 @@ void tst_QSslCertificate::threadSafeConstMethods()
|
|||
|
||||
}
|
||||
|
||||
void tst_QSslCertificate::version_data()
|
||||
{
|
||||
QTest::addColumn<QSslCertificate>("certificate");
|
||||
QTest::addColumn<QByteArray>("result");
|
||||
|
||||
QTest::newRow("null certificate") << QSslCertificate() << QByteArray();
|
||||
|
||||
QList<QSslCertificate> certs;
|
||||
certs << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
|
||||
|
||||
QTest::newRow("v3 certificate") << certs.first() << QByteArrayLiteral("3");
|
||||
|
||||
certs.clear();
|
||||
certs << QSslCertificate::fromPath(testDataDir + "/certificates/cert.pem");
|
||||
QTest::newRow("v1 certificate") << certs.first() << QByteArrayLiteral("1");
|
||||
}
|
||||
|
||||
void tst_QSslCertificate::version()
|
||||
{
|
||||
if (!QSslSocket::supportsSsl())
|
||||
return;
|
||||
|
||||
QFETCH(QSslCertificate, certificate);
|
||||
QFETCH(QByteArray, result);
|
||||
QCOMPARE(certificate.version(), result);
|
||||
}
|
||||
|
||||
#endif // QT_NO_SSL
|
||||
|
||||
QTEST_MAIN(tst_QSslCertificate)
|
||||
|
|
|
|||
|
|
@ -1935,7 +1935,7 @@ void tst_QAccessibility::lineEditTest()
|
|||
QVERIFY(iface->state().movable);
|
||||
QVERIFY(iface->state().focusable);
|
||||
QVERIFY(iface->state().selectable);
|
||||
QVERIFY(iface->state().hasPopup);
|
||||
QVERIFY(!iface->state().hasPopup);
|
||||
QCOMPARE(bool(iface->state().focused), le->hasFocus());
|
||||
|
||||
QString secret(QLatin1String("secret"));
|
||||
|
|
@ -1963,7 +1963,7 @@ void tst_QAccessibility::lineEditTest()
|
|||
QVERIFY(!(iface->state().movable));
|
||||
QVERIFY(iface->state().focusable);
|
||||
QVERIFY(iface->state().selectable);
|
||||
QVERIFY(iface->state().hasPopup);
|
||||
QVERIFY(!iface->state().hasPopup);
|
||||
QCOMPARE(bool(iface->state().focused), le->hasFocus());
|
||||
|
||||
QLineEdit *le2 = new QLineEdit(toplevel);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
#include "qdebug.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase()));
|
||||
|
|
@ -159,7 +159,7 @@ public:
|
|||
q.bindValue(2, 10);
|
||||
QVERIFY_SQL(q, exec());
|
||||
#ifdef Q_OS_LINUX
|
||||
pthread_yield();
|
||||
sched_yield();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -197,7 +197,7 @@ public:
|
|||
q1.clear();
|
||||
QVERIFY_SQL(q2, exec());
|
||||
#ifdef Q_OS_LINUX
|
||||
pthread_yield();
|
||||
sched_yield();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ private slots:
|
|||
void tildeExpansion();
|
||||
#endif // QT_BUILD_INTERNAL
|
||||
#endif
|
||||
void getFileUrl();
|
||||
|
||||
private:
|
||||
QByteArray userSettings;
|
||||
|
|
@ -1429,5 +1430,49 @@ void tst_QFiledialog::tildeExpansion()
|
|||
#endif // QT_BUILD_INTERNAL
|
||||
#endif
|
||||
|
||||
class DialogRejecter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DialogRejecter()
|
||||
{
|
||||
QTimer *timer = new QTimer(this);
|
||||
timer->setInterval(1000);
|
||||
connect(timer, &QTimer::timeout, this, &DialogRejecter::rejectFileDialog);
|
||||
timer->start();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void rejectFileDialog()
|
||||
{
|
||||
if (QWidget *w = QApplication::activeModalWidget())
|
||||
if (QDialog *d = qobject_cast<QDialog *>(w))
|
||||
d->reject();
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QFiledialog::getFileUrl()
|
||||
{
|
||||
// QTBUG-38672 , static functions should return empty Urls
|
||||
const QFileDialog::Options options = QFileDialog::DontUseNativeDialog;
|
||||
DialogRejecter dr;
|
||||
|
||||
QUrl url = QFileDialog::getOpenFileUrl(0, QStringLiteral("getOpenFileUrl"),
|
||||
QUrl(), QString(), Q_NULLPTR, options);
|
||||
QVERIFY(url.isEmpty());
|
||||
QVERIFY(!url.isValid());
|
||||
|
||||
url = QFileDialog::getExistingDirectoryUrl(0, QStringLiteral("getExistingDirectoryUrl"),
|
||||
QUrl(), options | QFileDialog::ShowDirsOnly);
|
||||
QVERIFY(url.isEmpty());
|
||||
QVERIFY(!url.isValid());
|
||||
|
||||
url = QFileDialog::getSaveFileUrl(0, QStringLiteral("getSaveFileUrl"),
|
||||
QUrl(), QString(), Q_NULLPTR, options);
|
||||
QVERIFY(url.isEmpty());
|
||||
QVERIFY(!url.isValid());
|
||||
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QFiledialog)
|
||||
#include "tst_qfiledialog.moc"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
|
|
@ -261,6 +261,7 @@ private slots:
|
|||
void taskQTBUG_18539_emitLayoutChanged();
|
||||
void taskQTBUG_8176_emitOnExpandAll();
|
||||
void taskQTBUG_34717_collapseAtBottom();
|
||||
void taskQTBUG_37813_crash();
|
||||
void testInitialFocus();
|
||||
};
|
||||
|
||||
|
|
@ -4327,5 +4328,31 @@ void tst_QTreeView::quickExpandCollapse()
|
|||
}
|
||||
#endif
|
||||
|
||||
void tst_QTreeView::taskQTBUG_37813_crash()
|
||||
{
|
||||
// QTBUG_37813: Crash in visual / logical index mapping in QTreeViewPrivate::adjustViewOptionsForIndex()
|
||||
// when hiding/moving columns. It is reproduceable with a QTreeWidget only.
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
QTreeWidget treeWidget;
|
||||
treeWidget.setDragEnabled(true);
|
||||
treeWidget.setColumnCount(2);
|
||||
QList<QTreeWidgetItem *> items;
|
||||
for (int r = 0; r < 2; ++r) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
for (int c = 0; c < treeWidget.columnCount(); ++c)
|
||||
item->setText(c, QString::fromLatin1("Row %1 Column %2").arg(r).arg(c));
|
||||
items.append(item);
|
||||
}
|
||||
treeWidget.addTopLevelItems(items);
|
||||
treeWidget.setColumnHidden(0, true);
|
||||
treeWidget.header()->moveSection(0, 1);
|
||||
QItemSelection sel(treeWidget.model()->index(0, 0), treeWidget.model()->index(0, 1));
|
||||
QRect rect;
|
||||
QAbstractItemViewPrivate *av = static_cast<QAbstractItemViewPrivate*>(qt_widget_private(&treeWidget));
|
||||
const QPixmap pixmap = av->renderToPixmap(sel.indexes(), &rect);
|
||||
QVERIFY(pixmap.size().isValid());
|
||||
#endif // QT_BUILD_INTERNAL
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTreeView)
|
||||
#include "tst_qtreeview.moc"
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@
|
|||
|
||||
#include "../../../qtest-config.h"
|
||||
|
||||
static inline void centerOnScreen(QWidget *w)
|
||||
{
|
||||
const QPoint offset = QPoint(w->width() / 2, w->height() / 2);
|
||||
w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset);
|
||||
}
|
||||
|
||||
class tst_QStyleSheetStyle : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -142,6 +148,8 @@ tst_QStyleSheetStyle::~tst_QStyleSheetStyle()
|
|||
void tst_QStyleSheetStyle::numinstances()
|
||||
{
|
||||
QWidget w;
|
||||
w.resize(200, 200);
|
||||
centerOnScreen(&w);
|
||||
QCommonStyle *style = new QCommonStyle;
|
||||
style->setParent(&w);
|
||||
QWidget c(&w);
|
||||
|
|
@ -531,7 +539,14 @@ void tst_QStyleSheetStyle::dynamicProperty()
|
|||
qApp->setStyleSheet(QString());
|
||||
|
||||
QString appStyle = qApp->style()->metaObject()->className();
|
||||
QPushButton pb1, pb2;
|
||||
QPushButton pb1(QStringLiteral("dynamicProperty_pb1"));
|
||||
pb1.setMinimumWidth(160);
|
||||
pb1.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 100));
|
||||
|
||||
QPushButton pb2(QStringLiteral("dynamicProperty_pb2"));
|
||||
pb2.setMinimumWidth(160);
|
||||
pb2.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 200));
|
||||
|
||||
pb1.setProperty("type", "critical");
|
||||
qApp->setStyleSheet("*[class~=\"QPushButton\"] { color: red; } *[type=\"critical\"] { background: white; }");
|
||||
QVERIFY(COLOR(pb1) == Qt::red);
|
||||
|
|
@ -675,6 +690,8 @@ void tst_QStyleSheetStyle::onWidgetDestroyed()
|
|||
void tst_QStyleSheetStyle::fontPrecedence()
|
||||
{
|
||||
QLineEdit edit;
|
||||
edit.setMinimumWidth(200);
|
||||
centerOnScreen(&edit);
|
||||
edit.show();
|
||||
QFont font;
|
||||
QVERIFY(FONTSIZE(edit) != 22); // Sanity check to make sure this test makes sense.
|
||||
|
|
@ -737,8 +754,9 @@ void tst_QStyleSheetStyle::focusColors()
|
|||
// ten pixels of the right color requires quite a many characters, as the
|
||||
// majority of the pixels will have slightly different colors due to the
|
||||
// anti-aliasing effect.
|
||||
#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC) && !(defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL))
|
||||
QSKIP("This is a fragile test which fails on many esoteric platforms because of focus problems. "
|
||||
#if !defined(Q_OS_WIN32) && !(defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL))
|
||||
QSKIP("This is a fragile test which fails on many esoteric platforms because of focus problems"
|
||||
" (for example, QTBUG-33959)."
|
||||
"That doesn't mean that the feature doesn't work in practice.");
|
||||
#endif
|
||||
QList<QWidget *> widgets;
|
||||
|
|
@ -768,6 +786,7 @@ void tst_QStyleSheetStyle::focusColors()
|
|||
layout->addWidget(widget);
|
||||
frame.setLayout(layout);
|
||||
|
||||
centerOnScreen(&frame);
|
||||
frame.show();
|
||||
QApplication::setActiveWindow(&frame);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&frame));
|
||||
|
|
@ -795,6 +814,9 @@ void tst_QStyleSheetStyle::focusColors()
|
|||
#ifndef QTEST_NO_CURSOR
|
||||
void tst_QStyleSheetStyle::hoverColors()
|
||||
{
|
||||
#ifdef Q_OS_OSX
|
||||
QSKIP("This test is fragile on Mac, most likely due to QTBUG-33959.");
|
||||
#endif
|
||||
QList<QWidget *> widgets;
|
||||
widgets << new QPushButton("TESTING TESTING");
|
||||
widgets << new QLineEdit("TESTING TESTING");
|
||||
|
|
@ -822,31 +844,22 @@ void tst_QStyleSheetStyle::hoverColors()
|
|||
layout->addWidget(widget);
|
||||
frame.setLayout(layout);
|
||||
|
||||
centerOnScreen(&frame);
|
||||
frame.show();
|
||||
|
||||
QApplication::setActiveWindow(&frame);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&frame));
|
||||
//move the mouse inside the widget, it should be colored
|
||||
QTest::mouseMove ( widget, QPoint(6,6));
|
||||
QTest::qWait(60);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "Numerous failures related to Qt::WA_UnderMouse, see QTBUGT-23685", Continue);
|
||||
#endif
|
||||
QVERIFY(widget->testAttribute(Qt::WA_UnderMouse));
|
||||
QTRY_VERIFY(widget->testAttribute(Qt::WA_UnderMouse));
|
||||
|
||||
QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
|
||||
frame.render(&image);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "Numerous failures related to Qt::WA_UnderMouse, see QTBUGT-23685", Continue);
|
||||
#endif
|
||||
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
|
||||
(QString::fromLatin1(widget->metaObject()->className())
|
||||
+ " did not contain background color #e8ff66").toLocal8Bit().constData());
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "Numerous failures related to Qt::WA_UnderMouse, see QTBUGT-23685", Continue);
|
||||
#endif
|
||||
QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
|
||||
(QString::fromLatin1(widget->metaObject()->className())
|
||||
+ " did not contain text color #ff0084").toLocal8Bit().constData());
|
||||
|
|
@ -866,9 +879,7 @@ void tst_QStyleSheetStyle::hoverColors()
|
|||
|
||||
//move the mouse again inside the widget, it should be colored
|
||||
QTest::mouseMove (widget, QPoint(5,5));
|
||||
QTest::qWait(60);
|
||||
|
||||
QVERIFY(widget->testAttribute(Qt::WA_UnderMouse));
|
||||
QTRY_VERIFY(widget->testAttribute(Qt::WA_UnderMouse));
|
||||
|
||||
frame.render(&image);
|
||||
|
||||
|
|
@ -904,35 +915,47 @@ public:
|
|||
|
||||
void tst_QStyleSheetStyle::background()
|
||||
{
|
||||
const int number = 4;
|
||||
QWidget* widgets[number];
|
||||
typedef QSharedPointer<QWidget> WidgetPtr;
|
||||
|
||||
const QString styleSheet = QStringLiteral("* { background-color: #e8ff66; }");
|
||||
QVector<WidgetPtr> widgets;
|
||||
const QPoint topLeft = QGuiApplication::primaryScreen()->availableGeometry().topLeft();
|
||||
// Testing inheritance styling of QDialog.
|
||||
widgets[0] = new SingleInheritanceDialog;
|
||||
widgets[0]->setStyleSheet("* { background-color: #e8ff66; }");
|
||||
widgets[1] = new DoubleInheritanceDialog;
|
||||
widgets[1]->setStyleSheet("* { background-color: #e8ff66; }");
|
||||
WidgetPtr toplevel(new SingleInheritanceDialog);
|
||||
toplevel->resize(200, 200);
|
||||
toplevel->move(topLeft + QPoint(20, 20));
|
||||
toplevel->setStyleSheet(styleSheet);
|
||||
widgets.append(toplevel);
|
||||
|
||||
toplevel = WidgetPtr(new DoubleInheritanceDialog);
|
||||
toplevel->resize(200, 200);
|
||||
toplevel->move(topLeft + QPoint(20, 320));
|
||||
toplevel->setStyleSheet(styleSheet);
|
||||
widgets.append(toplevel);
|
||||
|
||||
// Testing gradients in QComboBox.
|
||||
QLayout* layout;
|
||||
QComboBox* cb;
|
||||
// First color
|
||||
widgets[2] = new QDialog;
|
||||
layout = new QGridLayout;
|
||||
cb = new QComboBox;
|
||||
toplevel = WidgetPtr(new QDialog);
|
||||
toplevel->move(topLeft + QPoint(320, 20));
|
||||
QGridLayout *layout = new QGridLayout(toplevel.data());
|
||||
QComboBox* cb = new QComboBox;
|
||||
cb->setMinimumWidth(160);
|
||||
cb->setStyleSheet("* { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 #e8ff66, stop:1 #000000); }");
|
||||
layout->addWidget(cb);
|
||||
widgets[2]->setLayout(layout);
|
||||
layout->addWidget(cb, 0, 0);
|
||||
widgets.append(toplevel);
|
||||
// Second color
|
||||
widgets[3] = new QDialog;
|
||||
layout = new QGridLayout;
|
||||
toplevel = WidgetPtr(new QDialog);
|
||||
toplevel->move(topLeft + QPoint(320, 320));
|
||||
layout = new QGridLayout(toplevel.data());
|
||||
cb = new QComboBox;
|
||||
cb->setMinimumWidth(160);
|
||||
cb->setStyleSheet("* { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 #e8ff66, stop:1 #000000); }");
|
||||
layout->addWidget(cb);
|
||||
widgets[3]->setLayout(layout);
|
||||
|
||||
for (int c = 0; c < number; ++c) {
|
||||
QWidget* widget = widgets[c];
|
||||
layout->addWidget(cb, 0, 0);
|
||||
widgets.append(toplevel);
|
||||
|
||||
for (int c = 0; c < widgets.size(); ++c) {
|
||||
QWidget *widget = widgets.at(c).data();
|
||||
widget->setWindowTitle(QStringLiteral("background ") + QString::number(c));
|
||||
widget->show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(widget));
|
||||
|
||||
|
|
@ -941,12 +964,15 @@ void tst_QStyleSheetStyle::background()
|
|||
if (image.depth() < 24)
|
||||
QSKIP("Test doesn't support color depth < 24");
|
||||
|
||||
if (c == 2 && !QApplication::style()->objectName().compare(QLatin1String("fusion"), Qt::CaseInsensitive))
|
||||
QEXPECT_FAIL("", "QTBUG-21468", Abort);
|
||||
|
||||
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
|
||||
(QString::fromLatin1(widget->metaObject()->className())
|
||||
(QString::number(c) + QLatin1Char(' ') + QString::fromLatin1(widget->metaObject()->className())
|
||||
+ " did not contain background image with color #e8ff66")
|
||||
.toLocal8Bit().constData());
|
||||
|
||||
delete widget;
|
||||
widget->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -956,6 +982,7 @@ void tst_QStyleSheetStyle::tabAlignement()
|
|||
QTabWidget tabWidget(&topLevel);
|
||||
tabWidget.addTab(new QLabel("tab1"),"tab1");
|
||||
tabWidget.resize(QSize(400,400));
|
||||
centerOnScreen(&topLevel);
|
||||
topLevel.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
|
||||
QTabBar *bar = tabWidget.findChild<QTabBar*>();
|
||||
|
|
@ -1023,6 +1050,7 @@ void tst_QStyleSheetStyle::minmaxSizes()
|
|||
|
||||
tabWidget.setStyleSheet("QTabBar::tab { min-width:100px; max-width:130px; }");
|
||||
|
||||
centerOnScreen(&tabWidget);
|
||||
tabWidget.show();
|
||||
QTest::qWait(50);
|
||||
//i allow 4px additional border from the native style (hence the -2, <=2)
|
||||
|
|
@ -1050,6 +1078,7 @@ void tst_QStyleSheetStyle::task206238_twice()
|
|||
tw->addTab(new QLabel("foo"), "test");
|
||||
w.setCentralWidget(tw);
|
||||
w.setStyleSheet("background: red;");
|
||||
centerOnScreen(&w);
|
||||
w.show();
|
||||
QTest::qWait(20);
|
||||
QCOMPARE(BACKGROUND(w) , QColor("red"));
|
||||
|
|
@ -1219,6 +1248,8 @@ void tst_QStyleSheetStyle::proxyStyle()
|
|||
QString styleSheet("QPushButton {background-color: red; }");
|
||||
|
||||
QWidget *w = new QWidget;
|
||||
w->setMinimumWidth(160);
|
||||
centerOnScreen(w);
|
||||
QVBoxLayout *layout = new QVBoxLayout(w);
|
||||
|
||||
QPushButton *pb1 = new QPushButton(qApp->style()->objectName(), w);
|
||||
|
|
@ -1294,6 +1325,7 @@ void tst_QStyleSheetStyle::emptyStyleSheet()
|
|||
layout.addWidget(new QDateEdit(&w));
|
||||
layout.addWidget(new QGroupBox("some text", &w));
|
||||
|
||||
centerOnScreen(&w);
|
||||
w.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&w));
|
||||
//workaround the fact that the label sizehint is one pixel different the first time.
|
||||
|
|
@ -1315,13 +1347,30 @@ void tst_QStyleSheetStyle::emptyStyleSheet()
|
|||
img2.save("emptyStyleSheet_img2.png");
|
||||
}
|
||||
|
||||
QEXPECT_FAIL("", "QTBUG-21468", Abort);
|
||||
QCOMPARE(img1,img2);
|
||||
}
|
||||
|
||||
class ApplicationStyleSetter
|
||||
{
|
||||
public:
|
||||
explicit inline ApplicationStyleSetter(QStyle *s) : m_oldStyleName(QApplication::style()->objectName())
|
||||
{ QApplication::setStyle(s); }
|
||||
inline ~ApplicationStyleSetter()
|
||||
{ QApplication::setStyle(QStyleFactory::create(m_oldStyleName)); }
|
||||
|
||||
private:
|
||||
const QString m_oldStyleName;
|
||||
};
|
||||
|
||||
void tst_QStyleSheetStyle::toolTip()
|
||||
{
|
||||
qApp->setStyleSheet(QString());
|
||||
QWidget w;
|
||||
// Use "Fusion" to prevent the Vista style from clobbering the tooltip palette in polish().
|
||||
QStyle *fusionStyle = QStyleFactory::create(QLatin1String("Fusion"));
|
||||
QVERIFY(fusionStyle);
|
||||
ApplicationStyleSetter as(fusionStyle);
|
||||
QHBoxLayout layout(&w);
|
||||
w.setLayout(&layout);
|
||||
|
||||
|
|
@ -1349,11 +1398,12 @@ void tst_QStyleSheetStyle::toolTip()
|
|||
wid4->setToolTip("this is wid4");
|
||||
wid4->setObjectName("wid4");
|
||||
|
||||
centerOnScreen(&w);
|
||||
w.show();
|
||||
qApp->setActiveWindow(&w);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&w));
|
||||
|
||||
QColor normalToolTip = qApp->palette().toolTipBase().color();
|
||||
const QColor normalToolTip = QToolTip::palette().color(QPalette::Inactive, QPalette::ToolTipBase);
|
||||
QList<QWidget *> widgets;
|
||||
QList<QColor> colors;
|
||||
|
||||
|
|
@ -1372,12 +1422,13 @@ void tst_QStyleSheetStyle::toolTip()
|
|||
|
||||
QWidget *tooltip = 0;
|
||||
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
|
||||
if (widget->inherits("QTipLabel") && widget->isVisible()) {
|
||||
if (widget->inherits("QTipLabel")) {
|
||||
tooltip = widget;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QVERIFY(tooltip);
|
||||
QTRY_VERIFY(tooltip->isVisible()); // Wait until Roll-Effect is finished (Windows Vista)
|
||||
QCOMPARE(tooltip->palette().color(tooltip->backgroundRole()), col);
|
||||
}
|
||||
|
||||
|
|
@ -1394,6 +1445,8 @@ void tst_QStyleSheetStyle::embeddedFonts()
|
|||
{
|
||||
//task 235622 and 210551
|
||||
QSpinBox spin;
|
||||
spin.setMinimumWidth(160);
|
||||
spin.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 20));
|
||||
spin.show();
|
||||
spin.setStyleSheet("QSpinBox { font-size: 32px; }");
|
||||
QTest::qWait(20);
|
||||
|
|
@ -1411,6 +1464,8 @@ void tst_QStyleSheetStyle::embeddedFonts()
|
|||
|
||||
//task 242556
|
||||
QComboBox box;
|
||||
box.setMinimumWidth(160);
|
||||
box.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 120));
|
||||
box.setEditable(true);
|
||||
box.addItems(QStringList() << "First" << "Second" << "Third");
|
||||
box.setStyleSheet("QComboBox { font-size: 32px; }");
|
||||
|
|
@ -1483,6 +1538,7 @@ void tst_QStyleSheetStyle::complexWidgetFocus()
|
|||
layout->addWidget(widget);
|
||||
frame.setLayout(layout);
|
||||
|
||||
centerOnScreen(&frame);
|
||||
frame.show();
|
||||
QApplication::setActiveWindow(&frame);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&frame));
|
||||
|
|
@ -1507,6 +1563,7 @@ void tst_QStyleSheetStyle::task188195_baseBackground()
|
|||
{
|
||||
QTreeView tree;
|
||||
tree.setStyleSheet( "QTreeView:disabled { background-color:#ab1251; }" );
|
||||
tree.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 100));
|
||||
tree.show();
|
||||
QTest::qWait(20);
|
||||
QImage image(tree.width(), tree.height(), QImage::Format_ARGB32);
|
||||
|
|
@ -1527,6 +1584,7 @@ void tst_QStyleSheetStyle::task188195_baseBackground()
|
|||
QTableWidget table(12, 12);
|
||||
table.setItem(0, 0, new QTableWidgetItem());
|
||||
table.setStyleSheet( "QTableView {background-color: #ff0000}" );
|
||||
table.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(300, 100));
|
||||
table.show();
|
||||
QTest::qWait(20);
|
||||
image = QImage(table.width(), table.height(), QImage::Format_ARGB32);
|
||||
|
|
@ -1560,6 +1618,7 @@ void tst_QStyleSheetStyle::task232085_spinBoxLineEditBg()
|
|||
layout->addWidget(spinbox);
|
||||
frame.setLayout(layout);
|
||||
|
||||
centerOnScreen(&frame);
|
||||
frame.show();
|
||||
QApplication::setActiveWindow(&frame);
|
||||
spinbox->setFocus();
|
||||
|
|
@ -1619,6 +1678,7 @@ void tst_QStyleSheetStyle::QTBUG11658_cachecrash()
|
|||
Widget(QWidget *parent = 0)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setMinimumWidth(160);
|
||||
QVBoxLayout* pLayout = new QVBoxLayout(this);
|
||||
QCheckBox* pCheckBox = new QCheckBox(this);
|
||||
pLayout->addWidget(pCheckBox);
|
||||
|
|
@ -1633,6 +1693,7 @@ void tst_QStyleSheetStyle::QTBUG11658_cachecrash()
|
|||
Widget *w = new Widget();
|
||||
delete w;
|
||||
w = new Widget();
|
||||
centerOnScreen(w);
|
||||
w->show();
|
||||
|
||||
QVERIFY(QTest::qWaitForWindowExposed(w));
|
||||
|
|
@ -1653,6 +1714,8 @@ void tst_QStyleSheetStyle::QTBUG15910_crashNullWidget()
|
|||
}
|
||||
} w;
|
||||
w.setStyleSheet("* { background-color: white; color:black; border 3px solid yellow }");
|
||||
w.setMinimumWidth(160);
|
||||
centerOnScreen(&w);
|
||||
w.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&w));
|
||||
}
|
||||
|
|
@ -1675,6 +1738,7 @@ void tst_QStyleSheetStyle::QTBUG36933_brokenPseudoClassLookup()
|
|||
// parsing of this stylesheet must not crash, and it must be correctly applied
|
||||
widget.setStyleSheet(QStringLiteral("QHeaderView::section:vertical { background-color: #FF0000 }"));
|
||||
|
||||
centerOnScreen(&widget);
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
|
||||
|
|
@ -1685,6 +1749,8 @@ void tst_QStyleSheetStyle::QTBUG36933_brokenPseudoClassLookup()
|
|||
QHeaderView *verticalHeader = widget.verticalHeader();
|
||||
QImage image(verticalHeader->size(), QImage::Format_ARGB32);
|
||||
verticalHeader->render(&image);
|
||||
if (!QApplication::style()->objectName().compare(QLatin1String("fusion"), Qt::CaseInsensitive))
|
||||
QEXPECT_FAIL("", "QTBUG-21468", Abort);
|
||||
QVERIFY(testForColors(image, QColor(0xFF, 0x00, 0x00)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@ SUBDIRS=\
|
|||
!mac:SUBDIRS -= \
|
||||
qmacstyle \
|
||||
|
||||
!contains( styles, motif ):SUBDIRS -= \
|
||||
ios|android|qnx|*wince*:SUBDIRS -= \
|
||||
qstylesheetstyle \
|
||||
|
|
|
|||
|
|
@ -60,26 +60,26 @@ class XmlServer : public QThread
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XmlServer();
|
||||
XmlServer(QObject *parent = 0) : QThread(parent), quit_soon(false), listening(false) {}
|
||||
|
||||
bool quit_soon;
|
||||
bool listening;
|
||||
|
||||
protected:
|
||||
virtual void run();
|
||||
};
|
||||
|
||||
XmlServer::XmlServer()
|
||||
{
|
||||
quit_soon = false;
|
||||
}
|
||||
|
||||
#define CHUNK_SIZE 1
|
||||
#define CHUNK_SIZE 2048
|
||||
|
||||
void XmlServer::run()
|
||||
{
|
||||
QTcpServer srv;
|
||||
|
||||
if (!srv.listen(QHostAddress::Any, TEST_PORT))
|
||||
listening = srv.listen(QHostAddress::Any, TEST_PORT);
|
||||
if (!listening) {
|
||||
qWarning() << "Failed to listen on" << TEST_PORT << srv.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
srv.waitForNewConnection(100);
|
||||
|
|
@ -168,12 +168,9 @@ class tst_QXmlSimpleReader : public QObject
|
|||
QString prefix;
|
||||
};
|
||||
|
||||
tst_QXmlSimpleReader::tst_QXmlSimpleReader()
|
||||
tst_QXmlSimpleReader::tst_QXmlSimpleReader() : server(new XmlServer(this))
|
||||
{
|
||||
server = new XmlServer();
|
||||
server->setParent(this);
|
||||
server->start();
|
||||
QTest::qSleep(1000);
|
||||
}
|
||||
|
||||
tst_QXmlSimpleReader::~tst_QXmlSimpleReader()
|
||||
|
|
@ -568,16 +565,13 @@ void tst_QXmlSimpleReader::inputFromSocket()
|
|||
{
|
||||
QFETCH(QString, file_name);
|
||||
|
||||
QTRY_VERIFY(server->listening);
|
||||
|
||||
QTcpSocket sock;
|
||||
sock.connectToHost(QHostAddress::LocalHost, TEST_PORT);
|
||||
|
||||
const bool connectionSuccess = sock.waitForConnected();
|
||||
if(!connectionSuccess) {
|
||||
QTextStream out(stderr);
|
||||
out << "QTcpSocket::errorString()" << sock.errorString();
|
||||
}
|
||||
|
||||
QVERIFY(connectionSuccess);
|
||||
QVERIFY2(sock.waitForConnected(),
|
||||
qPrintable(QStringLiteral("Cannot connect on port ") + QString::number(TEST_PORT)
|
||||
+ QStringLiteral(": ") + sock.errorString()));
|
||||
|
||||
sock.write(file_name.toLocal8Bit() + "\n");
|
||||
QVERIFY(sock.waitForBytesWritten());
|
||||
|
|
|
|||
Loading…
Reference in New Issue