Merge 5.12 into 5.12.0

Change-Id: I31f8eff4fdfe56cbb7f1450be8d351991966c6d8
This commit is contained in:
Oswald Buddenhagen 2018-10-30 00:49:20 +01:00
commit 5f3518d0bf
24 changed files with 261 additions and 122 deletions

View File

@ -5,6 +5,10 @@
"QDocModule": "qtgui",
"QtUsage": "Used on Windows to implement OpenGL ES on top of DirectX. Configure with -no-opengl, or -opengl desktop to exclude.",
"Description": "The ANGLE library translates OpenGL ES API calls to hardware-supported APIs.",
"Homepage": "http://angleproject.org/",
"Version": "chromium/3280",
"License": "BSD 3-clause \"New\" or \"Revised\" License",
"LicenseId": "BSD-3-Clause",
"LicenseFile": "LICENSE",

View File

@ -41,6 +41,7 @@
#ifndef QENDIAN_H
#define QENDIAN_H
#include <QtCore/qfloat16.h>
#include <QtCore/qglobal.h>
// include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems
@ -151,6 +152,31 @@ template <> inline Q_DECL_CONSTEXPR qint8 qbswap<qint8>(qint8 source)
return source;
}
// floating specializations
template<typename Float>
Float qbswapFloatHelper(Float source)
{
// memcpy call in qFromUnaligned is recognized by optimizer as a correct way of type prunning
auto temp = qFromUnaligned<typename QIntegerForSizeof<Float>::Unsigned>(&source);
temp = qbswap(temp);
return qFromUnaligned<Float>(&temp);
}
template <> inline qfloat16 qbswap<qfloat16>(qfloat16 source)
{
return qbswapFloatHelper(source);
}
template <> inline float qbswap<float>(float source)
{
return qbswapFloatHelper(source);
}
template <> inline double qbswap<double>(double source)
{
return qbswapFloatHelper(source);
}
/*
* qbswap(const T src, const void *dest);
* Changes the byte order of \a src from big endian to little endian or vice versa

View File

@ -333,7 +333,7 @@ QIODevicePrivate::~QIODevicePrivate()
allowed. This flag currently only affects QFile. Other
classes might use this flag in the future, but until then
using this flag with any classes other than QFile may
result in undefined behavior.
result in undefined behavior. (since Qt 5.11)
\value ExistingOnly Fail if the file to be opened does not exist. This flag
must be specified alongside ReadOnly, WriteOnly, or
ReadWrite. Note that using this flag with ReadOnly alone
@ -341,7 +341,7 @@ QIODevicePrivate::~QIODevicePrivate()
not exist. This flag currently only affects QFile. Other
classes might use this flag in the future, but until then
using this flag with any classes other than QFile may
result in undefined behavior.
result in undefined behavior. (since Qt 5.11)
Certain flags, such as \c Unbuffered and \c Truncate, are
meaningless when used with some subclasses. Some of these

View File

@ -290,7 +290,8 @@ QPagedPaintDevicePrivate *QPagedPaintDevice::dd()
\value PdfVersion_A1b A PDF/A-1b compatible document is produced.
\since 5.10
\value PdfVersion_1_6 A PDF 1.6 compatible document is produced.
This value was added in Qt 5.12.
*/
/*!

View File

@ -213,7 +213,7 @@ public:
Envelope10 = Comm10E
};
enum PdfVersion { PdfVersion_1_4, PdfVersion_A1b };
enum PdfVersion { PdfVersion_1_4, PdfVersion_A1b, PdfVersion_1_6 };
// ### Qt6 Make these virtual
bool setPageLayout(const QPageLayout &pageLayout);

View File

@ -1547,7 +1547,14 @@ void QPdfEnginePrivate::writeHeader()
{
addXrefEntry(0,false);
xprintf("%%PDF-1.4\n");
static const QHash<QPdfEngine::PdfVersion, const char *> mapping {
{QPdfEngine::Version_1_4, "1.4"},
{QPdfEngine::Version_A1b, "1.4"},
{QPdfEngine::Version_1_6, "1.6"}
};
const char *verStr = mapping.value(pdfVersion, "1.4");
xprintf("%%PDF-%s\n", verStr);
xprintf("%%\303\242\303\243\n");
writeInfo();
@ -1880,6 +1887,19 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
}
}
qreal QPdfEnginePrivate::calcUserUnit() const
{
// PDF standards < 1.6 support max 200x200in pages (no UserUnit)
if (pdfVersion < QPdfEngine::Version_1_6)
return 1.0;
const int maxLen = qMax(currentPage->pageSize.width(), currentPage->pageSize.height());
if (maxLen <= 14400)
return 1.0; // for pages up to 200x200in (14400x14400 units) use default scaling
// for larger pages, rescale units so we can have up to 381x381km
return qMin(maxLen / 14400.0, 75000.0);
}
void QPdfEnginePrivate::writeFonts()
{
@ -1902,6 +1922,8 @@ void QPdfEnginePrivate::writePage()
uint resources = requestObject();
uint annots = requestObject();
qreal userUnit = calcUserUnit();
addXrefEntry(pages.constLast());
xprintf("<<\n"
"/Type /Page\n"
@ -1909,12 +1931,16 @@ void QPdfEnginePrivate::writePage()
"/Contents %d 0 R\n"
"/Resources %d 0 R\n"
"/Annots %d 0 R\n"
"/MediaBox [0 0 %d %d]\n"
">>\n"
"endobj\n",
"/MediaBox [0 0 %f %f]\n",
pageRoot, pageStream, resources, annots,
// make sure we use the pagesize from when we started the page, since the user may have changed it
currentPage->pageSize.width(), currentPage->pageSize.height());
currentPage->pageSize.width() / userUnit, currentPage->pageSize.height() / userUnit);
if (pdfVersion >= QPdfEngine::Version_1_6)
xprintf("/UserUnit %f\n", userUnit);
xprintf(">>\n"
"endobj\n");
addXrefEntry(resources);
xprintf("<<\n"
@ -2983,8 +3009,9 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
QTransform QPdfEnginePrivate::pageMatrix() const
{
qreal scale = 72./resolution;
QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height());
qreal userUnit = calcUserUnit();
qreal scale = 72. / userUnit / resolution;
QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height() / userUnit);
if (m_pageLayout.mode() != QPageLayout::FullPageMode) {
QRect r = m_pageLayout.paintRectPixels(resolution);
tmp.translate(r.left(), r.top());

View File

@ -171,7 +171,8 @@ public:
enum PdfVersion
{
Version_1_4,
Version_A1b
Version_A1b,
Version_1_6
};
QPdfEngine();
@ -300,6 +301,7 @@ private:
void writePageRoot();
void writeFonts();
void embedFont(QFontSubset *font);
qreal calcUserUnit() const;
QVector<int> xrefPositions;
QDataStream* stream;

View File

@ -170,11 +170,17 @@ void QPdfWriter::setPdfVersion(PdfVersion version)
{
Q_D(QPdfWriter);
static const QHash<QPdfWriter::PdfVersion, QPdfEngine::PdfVersion> engineMapping {
{QPdfWriter::PdfVersion_1_4, QPdfEngine::Version_1_4},
{QPdfWriter::PdfVersion_A1b, QPdfEngine::Version_A1b},
{QPdfWriter::PdfVersion_1_6, QPdfEngine::Version_1_6}
};
if (d->pdfVersion == version)
return;
d->pdfVersion = version;
d->engine->setPdfVersion(d->pdfVersion == QPdfWriter::PdfVersion_1_4 ? QPdfEngine::Version_1_4 : QPdfEngine::Version_A1b);
d->engine->setPdfVersion(engineMapping.value(version, QPdfEngine::Version_1_4));
}
/*!

View File

@ -472,7 +472,7 @@ class QInt64Set
{
public:
inline QInt64Set(int capacity = 64);
inline ~QInt64Set() {if (m_array) delete[] m_array;}
inline ~QInt64Set() {delete[] m_array;}
inline bool isValid() const {return m_array;}
void insert(quint64 key);
bool contains(quint64 key) const;
@ -493,10 +493,7 @@ inline QInt64Set::QInt64Set(int capacity)
{
m_capacity = primeForCount(capacity);
m_array = new quint64[m_capacity];
if (m_array)
clear();
else
m_capacity = 0;
clear();
}
bool QInt64Set::rehash(int capacity)
@ -506,28 +503,19 @@ bool QInt64Set::rehash(int capacity)
m_capacity = capacity;
m_array = new quint64[m_capacity];
if (m_array) {
clear();
if (oldArray) {
for (int i = 0; i < oldCapacity; ++i) {
if (oldArray[i] != UNUSED)
insert(oldArray[i]);
}
delete[] oldArray;
}
return true;
} else {
m_capacity = oldCapacity;
m_array = oldArray;
return false;
clear();
for (int i = 0; i < oldCapacity; ++i) {
if (oldArray[i] != UNUSED)
insert(oldArray[i]);
}
delete[] oldArray;
return true;
}
void QInt64Set::insert(quint64 key)
{
if (m_count > 3 * m_capacity / 4)
rehash(primeForCount(2 * m_capacity));
Q_ASSERT_X(m_array, "QInt64Hash<T>::insert", "Hash set not allocated.");
int index = int(key % m_capacity);
for (int i = 0; i < m_capacity; ++i) {
index += i;
@ -546,7 +534,6 @@ void QInt64Set::insert(quint64 key)
bool QInt64Set::contains(quint64 key) const
{
Q_ASSERT_X(m_array, "QInt64Hash<T>::contains", "Hash set not allocated.");
int index = int(key % m_capacity);
for (int i = 0; i < m_capacity; ++i) {
index += i;
@ -562,7 +549,6 @@ bool QInt64Set::contains(quint64 key) const
inline void QInt64Set::clear()
{
Q_ASSERT_X(m_array, "QInt64Hash<T>::clear", "Hash set not allocated.");
for (int i = 0; i < m_capacity; ++i)
m_array[i] = UNUSED;
m_count = 0;

View File

@ -86,6 +86,7 @@
#include <private/qguiapplication_p.h>
#include "qt_mac_p.h"
#include <qpa/qwindowsysteminterface.h>
#include <qwindowdefs.h>
QT_USE_NAMESPACE
@ -93,6 +94,7 @@ QT_USE_NAMESPACE
bool startedQuit;
NSObject <NSApplicationDelegate> *reflectionDelegate;
bool inLaunch;
QWindowList hiddenWindows;
}
+ (instancetype)sharedDelegate
@ -322,12 +324,28 @@ QT_USE_NAMESPACE
// fact that the application itself is hidden, which will cause a problem when
// the application is made visible again.
const QWindowList topLevelWindows = QGuiApplication::topLevelWindows();
for (QWindow *topLevelWindow : qAsConst(topLevelWindows)) {
if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible())
for (QWindow *topLevelWindow : topLevelWindows) {
if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible()) {
topLevelWindow->hide();
if ((topLevelWindow->type() & Qt::Tool) == Qt::Tool)
hiddenWindows << topLevelWindow;
}
}
}
- (void)applicationDidUnhide:(NSNotification *)notification
{
if (reflectionDelegate
&& [reflectionDelegate respondsToSelector:@selector(applicationDidUnhide:)])
[reflectionDelegate applicationDidUnhide:notification];
for (QWindow *window : qAsConst(hiddenWindows))
window->show();
hiddenWindows.clear();
}
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
if (reflectionDelegate

View File

@ -414,7 +414,8 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
// have the same effect as an update.
// Now we are ready to associate the view with the context
if ((m_context.view = view) != view) {
m_context.view = view;
if (m_context.view != view) {
qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context;
m_updateObservers.clear();
return false;

View File

@ -546,7 +546,7 @@ int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEven
else
QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, keyModifier);
QCoreApplication::processEvents();
QWasmEventDispatcher::maintainTimers();
return 1;
}

View File

@ -207,26 +207,26 @@ static inline MouseEvent eventFromMsg(const MSG &msg)
return {QEvent::MouseButtonPress, Qt::LeftButton};
case WM_LBUTTONUP:
return {QEvent::MouseButtonRelease, Qt::LeftButton};
case WM_LBUTTONDBLCLK:
return {QEvent::MouseButtonDblClick, Qt::LeftButton};
case WM_LBUTTONDBLCLK: // Qt QPA does not handle double clicks, send as press
return {QEvent::MouseButtonPress, Qt::LeftButton};
case WM_MBUTTONDOWN:
return {QEvent::MouseButtonPress, Qt::MidButton};
case WM_MBUTTONUP:
return {QEvent::MouseButtonRelease, Qt::MidButton};
case WM_MBUTTONDBLCLK:
return {QEvent::MouseButtonDblClick, Qt::MidButton};
return {QEvent::MouseButtonPress, Qt::MidButton};
case WM_RBUTTONDOWN:
return {QEvent::MouseButtonPress, Qt::RightButton};
case WM_RBUTTONUP:
return {QEvent::MouseButtonRelease, Qt::RightButton};
case WM_RBUTTONDBLCLK:
return {QEvent::MouseButtonDblClick, Qt::RightButton};
return {QEvent::MouseButtonPress, Qt::RightButton};
case WM_XBUTTONDOWN:
return {QEvent::MouseButtonPress, extraButton(msg.wParam)};
case WM_XBUTTONUP:
return {QEvent::MouseButtonRelease, extraButton(msg.wParam)};
case WM_XBUTTONDBLCLK:
return {QEvent::MouseButtonDblClick, extraButton(msg.wParam)};
return {QEvent::MouseButtonPress, extraButton(msg.wParam)};
case WM_NCMOUSEMOVE:
return {QEvent::NonClientAreaMouseMove, Qt::NoButton};
case WM_NCLBUTTONDOWN:
@ -234,19 +234,19 @@ static inline MouseEvent eventFromMsg(const MSG &msg)
case WM_NCLBUTTONUP:
return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton};
case WM_NCLBUTTONDBLCLK:
return {QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton};
return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton};
case WM_NCMBUTTONDOWN:
return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton};
case WM_NCMBUTTONUP:
return {QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton};
case WM_NCMBUTTONDBLCLK:
return {QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton};
return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton};
case WM_NCRBUTTONDOWN:
return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton};
case WM_NCRBUTTONUP:
return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton};
case WM_NCRBUTTONDBLCLK:
return {QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton};
return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton};
default: // WM_MOUSELEAVE
break;
}

View File

@ -280,7 +280,7 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
return false;
}
static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QPoint globalPos, QEvent::Type *eventType, Qt::MouseButton *mouseButton)
static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QEvent::Type *eventType, Qt::MouseButton *mouseButton)
{
static const QHash<POINTER_BUTTON_CHANGE_TYPE, Qt::MouseButton> buttonMapping {
{POINTER_CHANGE_FIRSTBUTTON_DOWN, Qt::LeftButton},
@ -334,28 +334,6 @@ static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeTyp
}
*mouseButton = buttonMapping.value(changeType, Qt::NoButton);
// Pointer messages lack a double click indicator. Check if this is the case here.
if (*eventType == QEvent::MouseButtonPress ||
*eventType == QEvent::NonClientAreaMouseButtonPress) {
static LONG lastTime = 0;
static Qt::MouseButton lastButton = Qt::NoButton;
static QEvent::Type lastEvent = QEvent::None;
static QPoint lastPos;
LONG messageTime = GetMessageTime();
if (*mouseButton == lastButton
&& *eventType == lastEvent
&& messageTime - lastTime < (LONG)GetDoubleClickTime()
&& qAbs(globalPos.x() - lastPos.x()) < GetSystemMetrics(SM_CXDOUBLECLK)
&& qAbs(globalPos.y() - lastPos.y()) < GetSystemMetrics(SM_CYDOUBLECLK)) {
*eventType = nonClient ? QEvent::NonClientAreaMouseButtonDblClick :
QEvent::MouseButtonDblClick;
}
lastTime = messageTime;
lastButton = *mouseButton;
lastEvent = *eventType;
lastPos = globalPos;
}
}
static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos)
@ -467,7 +445,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h
QEvent::Type eventType;
Qt::MouseButton button;
getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, globalPos, &eventType, &button);
getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, &eventType, &button);
if (et & QtWindows::NonClientEventFlag) {
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType,
@ -506,6 +484,9 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h
case WM_POINTERHWHEEL:
case WM_POINTERWHEEL: {
if (!isValidWheelReceiver(window))
return true;
int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam);
// Qt horizontal wheel rotation orientation is opposite to the one in WM_POINTERHWHEEL
@ -515,8 +496,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h
const QPoint angleDelta = (msg.message == WM_POINTERHWHEEL || (keyModifiers & Qt::AltModifier)) ?
QPoint(delta, 0) : QPoint(0, delta);
if (isValidWheelReceiver(window))
QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
return true;
}
case WM_POINTERLEAVE:
@ -530,7 +510,6 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
MSG msg, PVOID vTouchInfo, quint32 count)
{
Q_UNUSED(hwnd);
Q_UNUSED(et);
if (et & QtWindows::NonClientEventFlag)
return false; // Let DefWindowProc() handle Non Client messages.
@ -729,21 +708,46 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
// Process old-style mouse messages here.
bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
{
Q_UNUSED(et);
// Generate enqueued events.
flushTouchEvents(m_touchDevice);
flushTabletEvents();
*result = 0;
if (msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE)
if (et != QtWindows::MouseWheelEvent && msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE)
return false;
const QPoint localPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
const QPoint globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, localPos);
const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
QPoint localPos;
QPoint globalPos;
if ((et == QtWindows::MouseWheelEvent) || (et & QtWindows::NonClientEventFlag)) {
globalPos = eventPos;
localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, eventPos);
} else {
localPos = eventPos;
globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, eventPos);
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
if (et == QtWindows::MouseWheelEvent) {
if (!isValidWheelReceiver(window))
return true;
int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam);
// Qt horizontal wheel rotation orientation is opposite to the one in WM_MOUSEHWHEEL
if (msg.message == WM_MOUSEHWHEEL)
delta = -delta;
const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ?
QPoint(delta, 0) : QPoint(0, delta);
QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
return true;
}
if (msg.message == WM_MOUSELEAVE) {
if (window == m_currentWindow) {
QWindowSystemInterface::handleLeaveEvent(window);
@ -784,7 +788,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
m_windowUnderPointer = currentWindowUnderPointer;
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const Qt::MouseButtons mouseButtons = queryMouseButtons();
if (!discardEvent)

View File

@ -105,6 +105,9 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toLower();
if (hasXRandr())
xrandrSelectEvents();
initializeScreens();
#if QT_CONFIG(xcb_xinput)

View File

@ -250,7 +250,7 @@ protected:
bool event(QEvent *e) override;
private:
void selectXRandrEvents();
void xrandrSelectEvents();
QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const;
QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const;
QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow) const;

View File

@ -308,7 +308,7 @@ void QXcbBasicConnection::initializeXRandr()
return;
}
m_hasXRender = true;
m_hasXRandr = true;
m_xrenderVersion.first = xrenderQuery->major_version;
m_xrenderVersion.second = xrenderQuery->minor_version;
#endif
@ -358,7 +358,7 @@ void QXcbBasicConnection::initializeXRender()
return;
}
m_hasXRandr = true;
m_hasXRender = true;
m_xrandrFirstEvent = reply->first_event;
}

View File

@ -46,7 +46,7 @@
#include <xcb/xinerama.h>
void QXcbConnection::selectXRandrEvents()
void QXcbConnection::xrandrSelectEvents()
{
xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(setup());
for (; rootIter.rem; xcb_screen_next(&rootIter)) {
@ -270,8 +270,6 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen)
void QXcbConnection::initializeScreens()
{
selectXRandrEvents();
xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup());
int xcbScreenNumber = 0; // screen number in the xcb sense
QXcbScreen *primaryScreen = nullptr;
@ -284,7 +282,7 @@ void QXcbConnection::initializeScreens()
QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber);
m_virtualDesktops.append(virtualDesktop);
QList<QPlatformScreen *> siblings;
if (hasXRender()) {
if (hasXRandr()) {
// RRGetScreenResourcesCurrent is fast but it may return nothing if the
// configuration is not initialized wrt to the hardware. We should call
// RRGetScreenResources in this case.

View File

@ -149,7 +149,12 @@ void QPrinterPrivate::initEngines(QPrinter::OutputFormat format, const QPrinterI
printEngine = ps->createNativePrintEngine(printerMode, printerName);
paintEngine = ps->createPaintEngine(printEngine, printerMode);
} else {
const auto pdfEngineVersion = (pdfVersion == QPrinter::PdfVersion_1_4 ? QPdfEngine::Version_1_4 : QPdfEngine::Version_A1b);
static const QHash<QPrinter::PdfVersion, QPdfEngine::PdfVersion> engineMapping {
{QPrinter::PdfVersion_1_4, QPdfEngine::Version_1_4},
{QPrinter::PdfVersion_A1b, QPdfEngine::Version_A1b},
{QPrinter::PdfVersion_1_6, QPdfEngine::Version_1_6}
};
const auto pdfEngineVersion = engineMapping.value(pdfVersion, QPdfEngine::Version_1_4);
QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode, pdfEngineVersion);
paintEngine = pdfEngine;
printEngine = pdfEngine;

View File

@ -64,6 +64,9 @@ struct TestData
quint16 data16;
quint8 data8;
float dataFloat;
double dataDouble;
quint8 reserved;
};
@ -72,6 +75,7 @@ template <> quint8 getData(const TestData &d) { return d.data8; }
template <> quint16 getData(const TestData &d) { return d.data16; }
template <> quint32 getData(const TestData &d) { return d.data32; }
template <> quint64 getData(const TestData &d) { return d.data64; }
template <> float getData(const TestData &d) { return d.dataFloat; }
union RawTestData
{
@ -79,9 +83,39 @@ union RawTestData
TestData data;
};
static const TestData inNativeEndian = { Q_UINT64_C(0x0123456789abcdef), 0x00c0ffee, 0xcafe, 0xcf, '\0' };
static const RawTestData inBigEndian = { "\x01\x23\x45\x67\x89\xab\xcd\xef" "\x00\xc0\xff\xee" "\xca\xfe" "\xcf" };
static const RawTestData inLittleEndian = { "\xef\xcd\xab\x89\x67\x45\x23\x01" "\xee\xff\xc0\x00" "\xfe\xca" "\xcf" };
template <typename Float>
Float int2Float(typename QIntegerForSizeof<Float>::Unsigned i)
{
Float result = 0;
memcpy(reinterpret_cast<char *>(&result), reinterpret_cast<const char *>(&i), sizeof (Float));
return result;
}
static const TestData inNativeEndian = {
Q_UINT64_C(0x0123456789abcdef),
0x00c0ffee,
0xcafe,
0xcf,
int2Float<float>(0x00c0ffeeU),
int2Float<double>(Q_UINT64_C(0x0123456789abcdef)),
'\0'
};
static const RawTestData inBigEndian = {
"\x01\x23\x45\x67\x89\xab\xcd\xef"
"\x00\xc0\xff\xee"
"\xca\xfe"
"\xcf"
"\x00\xc0\xff\xee"
"\x01\x23\x45\x67\x89\xab\xcd\xef"
};
static const RawTestData inLittleEndian = {
"\xef\xcd\xab\x89\x67\x45\x23\x01"
"\xee\xff\xc0\x00"
"\xfe\xca"
"\xcf"
"\xee\xff\xc0\x00"
"\xef\xcd\xab\x89\x67\x45\x23\x01"
};
#define EXPAND_ENDIAN_TEST(endian) \
do { \

View File

@ -209,9 +209,6 @@ void tst_QIODevice::read_QByteArray()
//--------------------------------------------------------------------
void tst_QIODevice::unget()
{
#if defined(Q_OS_MAC)
QSKIP("The unget network test is unstable on Mac. See QTBUG-39983.");
#endif
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
buffer.write("ZXCV");

View File

@ -1,7 +1,5 @@
[sendPostedEvents]
windows
osx
[registerTimer]
windows
osx
winrt

View File

@ -962,9 +962,6 @@ void tst_QLocalSocket::processConnection()
#if !QT_CONFIG(process)
QSKIP("No qprocess support", SkipAll);
#else
#ifdef Q_OS_MAC
QSKIP("The processConnection test is unstable on Mac. See QTBUG-39986.");
#endif
#ifdef Q_OS_WIN
const QString exeSuffix = QStringLiteral(".exe");

View File

@ -51,10 +51,15 @@
// Will try to wait for the condition while allowing event processing
// for a maximum of 5 seconds.
#define TRY_WAIT(expr) \
#define TRY_WAIT(expr, timedOut) \
do { \
*timedOut = true; \
const int step = 50; \
for (int __i = 0; __i < 5000 && !(expr); __i+=step) { \
for (int __i = 0; __i < 5000; __i += step) { \
if (expr) { \
*timedOut = false; \
break; \
} \
QTest::qWait(step); \
} \
} while(0)
@ -123,6 +128,8 @@ private slots:
protected:
bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList());
QModelIndex prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2 = nullptr,
QSignalSpy **spy3 = nullptr);
private:
QFileSystemModel *model;
@ -306,7 +313,11 @@ void tst_QFileSystemModel::iconProvider()
bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs)
{
//qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files;
TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount));
bool timedOut = false;
TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount), &timedOut);
if (timedOut)
return false;
for (int i = 0; i < initial_dirs.count(); ++i) {
QDir dir(test_path);
if (!dir.exists()) {
@ -363,23 +374,45 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi
return true;
}
void tst_QFileSystemModel::rowCount()
QModelIndex tst_QFileSystemModel::prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2,
QSignalSpy **spy3)
{
QString tmp = flatDirTestPath;
QVERIFY(createFiles(tmp, QStringList()));
if (model->rowCount(model->index(test_path)) != 0)
return QModelIndex();
QSignalSpy spy2(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
QSignalSpy spy3(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
if (spy2)
*spy2 = new QSignalSpy(model, &QFileSystemModel::rowsInserted);
if (spy3)
*spy3 = new QSignalSpy(model, &QFileSystemModel::rowsAboutToBeInserted);
QStringList files = QStringList() << "b" << "d" << "f" << "h" << "j" << ".a" << ".c" << ".e" << ".g";
QStringList files = { "b", "d", "f", "h", "j", ".a", ".c", ".e", ".g" };
QString l = "b,d,f,h,j,.a,.c,.e,.g";
QVERIFY(createFiles(tmp, files));
if (!createFiles(test_path, files))
return QModelIndex();
QModelIndex root = model->setRootPath(tmp);
QTRY_COMPARE(model->rowCount(root), 5);
QVERIFY(spy2.count() > 0);
QVERIFY(spy3.count() > 0);
QModelIndex root = model->setRootPath(test_path);
if (!root.isValid())
return QModelIndex();
bool timedOut = false;
TRY_WAIT(model->rowCount(root) == 5, &timedOut);
if (timedOut)
return QModelIndex();
return root;
}
void tst_QFileSystemModel::rowCount()
{
const QString tmp = flatDirTestPath;
QSignalSpy *spy2 = nullptr;
QSignalSpy *spy3 = nullptr;
QModelIndex root = prepareTestModelRoot(flatDirTestPath, &spy2, &spy3);
QVERIFY(root.isValid());
QVERIFY(spy2 && spy2->count() > 0);
QVERIFY(spy3 && spy3->count() > 0);
}
void tst_QFileSystemModel::rowsInserted_data()
@ -401,9 +434,9 @@ static inline QString lastEntry(const QModelIndex &root)
void tst_QFileSystemModel::rowsInserted()
{
QString tmp = flatDirTestPath;
rowCount();
QModelIndex root = model->index(model->rootPath());
const QString tmp = flatDirTestPath;
QModelIndex root = prepareTestModelRoot(tmp);
QVERIFY(root.isValid());
QFETCH(int, ascending);
QFETCH(int, count);
@ -454,9 +487,9 @@ void tst_QFileSystemModel::rowsRemoved_data()
void tst_QFileSystemModel::rowsRemoved()
{
QString tmp = flatDirTestPath;
rowCount();
QModelIndex root = model->index(model->rootPath());
const QString tmp = flatDirTestPath;
QModelIndex root = prepareTestModelRoot(tmp);
QVERIFY(root.isValid());
QFETCH(int, count);
QFETCH(int, ascending);
@ -509,9 +542,9 @@ void tst_QFileSystemModel::dataChanged()
{
QSKIP("This can't be tested right now since we don't watch files, only directories.");
QString tmp = flatDirTestPath;
rowCount();
QModelIndex root = model->index(model->rootPath());
const QString tmp = flatDirTestPath;
QModelIndex root = prepareTestModelRoot(tmp);
QVERIFY(root.isValid());
QFETCH(int, count);
QFETCH(int, assending);