Merge "Merge remote-tracking branch 'origin/5.5' into 5.6" into refs/staging/5.6

This commit is contained in:
Liang Qi 2015-11-04 13:06:17 +00:00 committed by The Qt Project
commit e304dfb2d3
17 changed files with 200 additions and 61 deletions

View File

@ -61,6 +61,9 @@
#if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500
# define HAVE_WAITID 1
#endif
#if !defined(WEXITED) || !defined(WNOWAIT)
# undef HAVE_WAITID
#endif
#if defined(__FreeBSD__)
# define HAVE_PIPE2 1

View File

@ -107,13 +107,15 @@ public class QtNative
}
}
public static boolean openURL(String url)
public static boolean openURL(String url, String mime)
{
boolean ok = true;
try {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (!mime.isEmpty())
intent.setDataAndType(uri, mime);
activity().startActivity(intent);
} catch (Exception e) {
e.printStackTrace();

View File

@ -41,15 +41,15 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/preprocessor/Token.cpp
# NOTE: 'flex' and 'bison' can be found in qt5/gnuwin32/bin
flex.commands = $$addGnuPath(flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
flex.output = ${QMAKE_FILE_BASE}.cpp
flex.commands = $$addGnuPath(flex) --noline --nounistd --outfile=${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
flex.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}.cpp
flex.input = FLEX_SOURCES
flex.dependency_type = TYPE_C
flex.variable_out = GENERATED_SOURCES
QMAKE_EXTRA_COMPILERS += flex
bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --output=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
bison.output = ${QMAKE_FILE_BASE}.cpp
bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --output=${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
bison.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}.cpp
bison.input = BISON_SOURCES
bison.dependency_type = TYPE_C
bison.variable_out = GENERATED_SOURCES

View File

@ -163,16 +163,18 @@ SOURCES += \
# NOTE: 'flex' and 'bison' can be found in qt5/gnuwin32/bin
flex.commands = $$addGnuPath(flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
flex.output = ${QMAKE_FILE_BASE}_lex.cpp
flex.commands = $$addGnuPath(flex) --noline --nounistd --outfile=${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
flex.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_lex.cpp
flex.input = FLEX_SOURCES
flex.dependency_type = TYPE_C
flex.variable_out = GENERATED_SOURCES
QMAKE_EXTRA_COMPILERS += flex
bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_BASE}_tab.h \
--output=${QMAKE_FILE_BASE}_tab.cpp ${QMAKE_FILE_NAME}
bison.output = ${QMAKE_FILE_BASE}_tab.h
defineReplace(myDirName) { return($$dirname(1)) }
bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_OUT} \
--output=${QMAKE_FUNC_FILE_OUT_myDirName}$$QMAKE_DIR_SEP${QMAKE_FILE_OUT_BASE}.cpp \
${QMAKE_FILE_NAME}
bison.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.h
bison.input = BISON_SOURCES
bison.dependency_type = TYPE_C
bison.variable_out = GENERATED_SOURCES
@ -182,10 +184,10 @@ QMAKE_EXTRA_COMPILERS += bison
# have one output file even if the command generates two.
MAKEFILE_NOOP_COMMAND = @echo -n
msvc: MAKEFILE_NOOP_COMMAND = @echo >NUL
bison_impl.output = ${QMAKE_FILE_BASE}_tab.cpp
bison_impl.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.cpp
bison_impl.input = BISON_SOURCES
bison_impl.commands = $$MAKEFILE_NOOP_COMMAND
bison_impl.depends = ${QMAKE_FILE_BASE}_tab.h
bison_impl.output = ${QMAKE_FILE_BASE}_tab.cpp
bison_impl.depends = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.h
bison_impl.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.cpp
bison_impl.variable_out = GENERATED_SOURCES
QMAKE_EXTRA_COMPILERS += bison_impl

View File

@ -53,6 +53,8 @@ CONFIG(debug, debug|release) {
DEFINES += NDEBUG
}
!isEmpty(BUILD_PASS): BUILDSUBDIR = $$lower($$BUILD_PASS)/
# c++11 is needed by MinGW to get support for unordered_map.
CONFIG += stl exceptions c++11

View File

@ -68,8 +68,8 @@
#if defined(Q_OS_BSD4)
# if defined(Q_OS_NETBSD)
define QT_STATFSBUF struct statvfs
define QT_STATFS ::statvfs
# define QT_STATFSBUF struct statvfs
# define QT_STATFS ::statvfs
# else
# define QT_STATFSBUF struct statfs
# define QT_STATFS ::statfs
@ -507,9 +507,15 @@ void QStorageInfoPrivate::retrieveVolumeInfo()
valid = true;
ready = true;
#if defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD)
bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize;
bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize;
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize;
#else
bytesTotal = statfs_buf.f_blocks * statfs_buf.f_frsize;
bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize;
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize;
#endif
blockSize = statfs_buf.f_bsize;
#if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4)
#if defined(_STATFS_F_FLAGS)

View File

@ -186,6 +186,10 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
case ERROR_PIPE_NOT_CONNECTED:
pipeBroken = true;
break;
case ERROR_OPERATION_ABORTED:
if (stopped)
break;
// fall through
default:
emit winError(errorCode, QLatin1String("QWindowsPipeReader::notified"));
pipeBroken = true;

View File

@ -33,6 +33,7 @@
#include "qwinoverlappedionotifier_p.h"
#include <qdebug.h>
#include <qatomic.h>
#include <qelapsedtimer.h>
#include <qmutex.h>
#include <qpointer.h>
@ -99,6 +100,7 @@ public:
{
}
OVERLAPPED *waitForAnyNotified(int msecs);
void notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
OVERLAPPED *_q_notified();
@ -108,6 +110,7 @@ public:
HANDLE hHandle;
HANDLE hSemaphore;
HANDLE hResultsMutex;
QAtomicInt waiting;
QQueue<IOResult> results;
};
@ -286,6 +289,47 @@ void QWinOverlappedIoNotifier::setEnabled(bool enabled)
d->iocp->unregisterNotifier(d);
}
OVERLAPPED *QWinOverlappedIoNotifierPrivate::waitForAnyNotified(int msecs)
{
if (!iocp->isRunning()) {
qWarning("Called QWinOverlappedIoNotifier::waitForAnyNotified on inactive notifier.");
return 0;
}
if (msecs == 0)
iocp->drainQueue();
const DWORD wfso = WaitForSingleObject(hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs));
switch (wfso) {
case WAIT_OBJECT_0:
ReleaseSemaphore(hSemaphore, 1, NULL);
return _q_notified();
case WAIT_TIMEOUT:
return 0;
default:
qErrnoWarning("QWinOverlappedIoNotifier::waitForAnyNotified: WaitForSingleObject failed.");
return 0;
}
}
class QScopedAtomicIntIncrementor
{
public:
QScopedAtomicIntIncrementor(QAtomicInt &i)
: m_int(i)
{
++m_int;
}
~QScopedAtomicIntIncrementor()
{
--m_int;
}
private:
QAtomicInt &m_int;
};
/*!
* Wait synchronously for any notified signal.
*
@ -296,24 +340,9 @@ void QWinOverlappedIoNotifier::setEnabled(bool enabled)
OVERLAPPED *QWinOverlappedIoNotifier::waitForAnyNotified(int msecs)
{
Q_D(QWinOverlappedIoNotifier);
if (!d->iocp->isRunning()) {
qWarning("Called QWinOverlappedIoNotifier::waitForAnyNotified on inactive notifier.");
return 0;
}
if (msecs == 0)
d->iocp->drainQueue();
switch (WaitForSingleObject(d->hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs))) {
case WAIT_OBJECT_0:
ReleaseSemaphore(d->hSemaphore, 1, NULL);
return d->_q_notified();
case WAIT_TIMEOUT:
return 0;
default:
qErrnoWarning("QWinOverlappedIoNotifier::waitForAnyNotified: WaitForSingleObject failed.");
return 0;
}
QScopedAtomicIntIncrementor saii(d->waiting);
OVERLAPPED *result = d->waitForAnyNotified(msecs);
return result;
}
/*!
@ -324,6 +353,8 @@ OVERLAPPED *QWinOverlappedIoNotifier::waitForAnyNotified(int msecs)
*/
bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped)
{
Q_D(QWinOverlappedIoNotifier);
QScopedAtomicIntIncrementor saii(d->waiting);
int t = msecs;
QElapsedTimer stopWatch;
stopWatch.start();
@ -350,7 +381,8 @@ void QWinOverlappedIoNotifierPrivate::notify(DWORD numberOfBytes, DWORD errorCod
results.enqueue(IOResult(numberOfBytes, errorCode, overlapped));
ReleaseMutex(hResultsMutex);
ReleaseSemaphore(hSemaphore, 1, NULL);
emit q->_q_notify();
if (!waiting)
emit q->_q_notify();
}
OVERLAPPED *QWinOverlappedIoNotifierPrivate::_q_notified()

View File

@ -1784,8 +1784,9 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
#endif
} else {
#ifndef QT_NO_BEARERMANAGEMENT
QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)),
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection);
if (session)
QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)),
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection);
#endif
}

View File

@ -33,8 +33,9 @@
#include "qandroidplatformservices.h"
#include <QUrl>
#include <QDir>
#include <QFile>
#include <QDebug>
#include <QMimeDatabase>
#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
@ -43,13 +44,27 @@ QAndroidPlatformServices::QAndroidPlatformServices()
{
}
bool QAndroidPlatformServices::openUrl(const QUrl &url)
bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
{
QString mime;
QUrl url(theUrl);
// if the file is local, we need to pass the MIME type, otherwise Android
// does not start an Intent to view this file
if ((url.scheme().isEmpty() && QFile::exists(url.path())) || url.isLocalFile()) {
// a real URL including the scheme is needed, else the Intent can not be started
url.setScheme(QLatin1String("file"));
QMimeDatabase mimeDb;
mime = mimeDb.mimeTypeForUrl(url).name();
}
QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime);
return QJNIObjectPrivate::callStaticMethod<jboolean>(QtAndroid::applicationClass(),
"openURL",
"(Ljava/lang/String;)Z",
urlString.object());
"(Ljava/lang/String;Ljava/lang/String;)Z",
urlString.object(), mimeString.object());
}
bool QAndroidPlatformServices::openDocument(const QUrl &url)

View File

@ -56,6 +56,14 @@ static void convertLineOffset(QAccessibleTextInterface *text, int &line, int &of
do {
curStart = curEnd;
text->textAtOffset(curStart, QAccessible::LineBoundary, &curStart, &curEnd);
// If the text is empty then we just return
if (curStart == -1 || curEnd == -1) {
if (start)
*start = 0;
if (end)
*end = 0;
return;
}
++curLine;
{
// check for a case where a single word longer than the text edit's width and gets wrapped

View File

@ -201,12 +201,14 @@ void QWindowsUser32DLL::init()
bool QWindowsUser32DLL::initTouch()
{
QSystemLibrary library(QStringLiteral("user32"));
isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow"));
registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow"));
unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow"));
getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo"));
closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle"));
if (!isTouchWindow && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
QSystemLibrary library(QStringLiteral("user32"));
isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow"));
registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow"));
unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow"));
getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo"));
closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle"));
}
return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle;
}
@ -359,6 +361,36 @@ QWindowsContext::~QWindowsContext()
m_instance = 0;
}
bool QWindowsContext::initTouch()
{
return initTouch(QWindowsIntegration::instance()->options());
}
bool QWindowsContext::initTouch(unsigned integrationOptions)
{
if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
return true;
QTouchDevice *touchDevice = d->m_mouseHandler.ensureTouchDevice();
if (!touchDevice)
return false;
#ifndef Q_OS_WINCE
if (!QWindowsContext::user32dll.initTouch()) {
delete touchDevice;
return false;
}
#endif // !Q_OS_WINCE
if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch))
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(touchDevice);
d->m_systemInfo |= QWindowsContext::SI_SupportsTouch;
return true;
}
void QWindowsContext::setTabletAbsoluteRange(int a)
{
#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)

View File

@ -170,6 +170,9 @@ public:
explicit QWindowsContext();
~QWindowsContext();
bool initTouch();
bool initTouch(unsigned integrationOptions); // For calls from QWindowsIntegration::QWindowsIntegration() only.
int defaultDPI() const;
QString registerWindowClass(const QWindow *w);

View File

@ -226,17 +226,7 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
qCDebug(lcQpaWindows)
<< __FUNCTION__ << "DpiAwareness=" << dpiAwareness;
QTouchDevice *touchDevice = m_context.touchDevice();
if (touchDevice) {
#ifdef Q_OS_WINCE
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
#else
if (!(m_options & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) {
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
}
#endif
QWindowSystemInterface::registerTouchDevice(touchDevice);
}
m_context.initTouch(m_options);
}
QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate()

View File

@ -150,12 +150,19 @@ static inline QTouchDevice *createTouchDevice()
QWindowsMouseHandler::QWindowsMouseHandler() :
m_windowUnderMouse(0),
m_trackedWindow(0),
m_touchDevice(createTouchDevice()),
m_touchDevice(Q_NULLPTR),
m_leftButtonDown(false),
m_previousCaptureWindow(0)
{
}
QTouchDevice *QWindowsMouseHandler::ensureTouchDevice()
{
if (!m_touchDevice)
m_touchDevice = createTouchDevice();
return m_touchDevice;
}
Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
{
Qt::MouseButtons result = 0;
@ -476,7 +483,11 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
typedef QWindowSystemInterface::TouchPoint QTouchPoint;
typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList;
Q_ASSERT(m_touchDevice);
if (!QWindowsContext::instance()->initTouch()) {
qWarning("Unable to initialize touch handling.");
return true;
}
const QScreen *screen = window->screen();
if (!screen)
screen = QGuiApplication::primaryScreen();
@ -492,8 +503,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
touchPoints.reserve(winTouchPointCount);
Qt::TouchPointStates allStates = 0;
Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo);
QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
for (int i = 0; i < winTouchPointCount; ++i) {
const TOUCHINPUT &winTouchInput = winTouchInputs[i];

View File

@ -52,6 +52,7 @@ public:
QWindowsMouseHandler();
QTouchDevice *touchDevice() const { return m_touchDevice; }
QTouchDevice *ensureTouchDevice();
bool translateMouseEvent(QWindow *widget, HWND hwnd,
QtWindows::WindowsEventType t, MSG msg,

View File

@ -98,6 +98,7 @@ private slots:
void removeServer();
void recycleServer();
void recycleClientSocket();
void multiConnect();
void writeOnlySocket();
@ -954,6 +955,34 @@ void tst_QLocalSocket::recycleServer()
QVERIFY(server.nextPendingConnection() != 0);
}
void tst_QLocalSocket::recycleClientSocket()
{
const QByteArrayList lines = QByteArrayList() << "Have you heard of that new band"
<< "\"1023 Megabytes\"?"
<< "They haven't made it to a gig yet.";
QLocalServer server;
const QString serverName = QStringLiteral("recycleClientSocket");
QVERIFY(server.listen(serverName));
QLocalSocket client;
QSignalSpy clientReadyReadSpy(&client, SIGNAL(readyRead()));
QSignalSpy clientErrorSpy(&client, SIGNAL(error(QLocalSocket::LocalSocketError)));
for (int i = 0; i < lines.count(); ++i) {
client.abort();
clientReadyReadSpy.clear();
client.connectToServer(serverName);
QVERIFY(client.waitForConnected());
QVERIFY(server.waitForNewConnection());
QLocalSocket *serverSocket = server.nextPendingConnection();
QVERIFY(serverSocket);
connect(serverSocket, &QLocalSocket::disconnected, &QLocalSocket::deleteLater);
serverSocket->write(lines.at(i));
serverSocket->flush();
QVERIFY(clientReadyReadSpy.wait());
QCOMPARE(client.readAll(), lines.at(i));
QVERIFY(clientErrorSpy.isEmpty());
}
}
void tst_QLocalSocket::multiConnect()
{
QLocalServer server;