From 0f9ca217d0f479756e50459473cad7371f29047c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 8 Apr 2016 10:44:12 +0200 Subject: winrt: support additional activation modes Besides launching a WinRT application it can also be activated, for instance via an uri protocol, as a share target or file open event. In those cases we need to resume the main thread, which only happened for regular launches so far. In addition we create and post an activation event, which can be caught from the user application. However this requires a QCoreApplication object to be created from the main thread, hence try to query the eventdispatcher with a timeout. Task-number: QTBUG-49276 Change-Id: I4ceca59dd3b062d9a5e49d1ad80334360aafbd6f Reviewed-by: Oliver Wolff --- src/winmain/qtmain_winrt.cpp | 47 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 9e5f206ea5..81ca07e447 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -187,12 +187,43 @@ public: } private: + HRESULT activatedLaunch(IInspectable *activateArgs) { + QCoreApplication *app = QCoreApplication::instance(); + + // Check whether the app already runs + if (!app) { +#if _MSC_VER >= 1900 + // I*EventArgs have no launch arguments, hence we + // need to prepend the application binary manually + wchar_t fn[513]; + DWORD res = GetModuleFileName(0, fn, 512); + + if (SUCCEEDED(res)) + args.prepend(QString::fromWCharArray(fn, res).toUtf8().data()); +#endif _MSC_VER >= 1900 + + ResumeThread(mainThread); + + // We give main() a max of 100ms to create an application object. + // No eventhandling needs to happen at that point, all we want is + // append our activation event + int iterations = 0; + while (true) { + app = QCoreApplication::instance(); + if (app || iterations++ > 10) + break; + Sleep(10); + } + } + + if (app) + QCoreApplication::postEvent(app, new QActivationEvent(activateArgs)); + return S_OK; + } + HRESULT __stdcall OnActivated(IActivatedEventArgs *args) Q_DECL_OVERRIDE { - QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher(); - if (dispatcher) - QCoreApplication::postEvent(dispatcher, new QActivationEvent(args)); - return S_OK; + return activatedLaunch(args); } HRESULT __stdcall OnLaunched(ILaunchActivatedEventArgs *launchArgs) Q_DECL_OVERRIDE @@ -290,8 +321,7 @@ private: HRESULT __stdcall OnFileActivated(IFileActivatedEventArgs *args) Q_DECL_OVERRIDE { - Q_UNUSED(args); - return S_OK; + return activatedLaunch(args); } HRESULT __stdcall OnSearchActivated(ISearchActivatedEventArgs *args) Q_DECL_OVERRIDE @@ -302,8 +332,7 @@ private: HRESULT __stdcall OnShareTargetActivated(IShareTargetActivatedEventArgs *args) Q_DECL_OVERRIDE { - Q_UNUSED(args); - return S_OK; + return activatedLaunch(args); } HRESULT __stdcall OnFileOpenPickerActivated(IFileOpenPickerActivatedEventArgs *args) Q_DECL_OVERRIDE @@ -334,7 +363,7 @@ private: ComPtr core; QByteArray commandLine; QVarLengthArray args; - HANDLE mainThread; + HANDLE mainThread{0}; HANDLE pidFile; }; -- cgit v1.2.3 From 3b98467ebe0e447d8343457310827e18706e9550 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 8 Apr 2016 07:39:41 +0200 Subject: winrt: Try to acquire CoreDispatcher from multiple sources When the system launches the application via different activation mode (eg. app registered for sharing) no main window will be created. Hence accessing the core window will return null and event dispatcher initialization will fail. In that case iterate through all available views and try to get access to their dispatcher to be able to invoke code on the xaml thread. Task-number: QTBUG-49276 Change-Id: I8c78baa27747a0465ff7a1b2ead6c9e03f0e05a8 Reviewed-by: Oliver Wolff --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 31 +++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index ca4ba72b66..d115a3db2a 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -50,6 +50,7 @@ using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::System::Threading; using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; using namespace ABI::Windows::UI::Core; using namespace ABI::Windows::ApplicationModel::Core; @@ -179,8 +180,34 @@ HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function & ComPtr window; hr = view->get_CoreWindow(&window); Q_ASSERT_SUCCEEDED(hr); - hr = window->get_Dispatcher(&dispatcher); - Q_ASSERT_SUCCEEDED(hr); + if (!window) { + // In case the application is launched via activation + // there might not be a main view (eg ShareTarget). + // Hence iterate through the available views and try to find + // a dispatcher in there + ComPtr> appViews; + hr = application->get_Views(&appViews); + Q_ASSERT_SUCCEEDED(hr); + quint32 count; + hr = appViews->get_Size(&count); + Q_ASSERT_SUCCEEDED(hr); + for (quint32 i = 0; i < count; ++i) { + hr = appViews->GetAt(i, &view); + Q_ASSERT_SUCCEEDED(hr); + hr = view->get_CoreWindow(&window); + Q_ASSERT_SUCCEEDED(hr); + if (window) { + hr = window->get_Dispatcher(&dispatcher); + Q_ASSERT_SUCCEEDED(hr); + if (dispatcher) + break; + } + } + Q_ASSERT(dispatcher); + } else { + hr = window->get_Dispatcher(&dispatcher); + Q_ASSERT_SUCCEEDED(hr); + } } HRESULT hr; -- cgit v1.2.3 From dbe9a8c9696428529cacb9dd4e004db99914b56e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 12 Apr 2016 16:05:10 +0200 Subject: Don't copy the functor object for each signal emission The behavior was different in the variadic template code and in the C++98 code. The code without variadic template support was not copying the functor object (e.g. a lambda) before calling it. However, in the variadic template section, QtPrivate::FunctorCall::call took the functor by value instead of by reference resulting in a copy. QtPrivate::FunctorCall::call is a helper function for QtPrivate::FunctionPointer::call which is only needed for variadic template expension. [ChangeLog][QtCore][QObject] If the compiler supports variadic templates, no longer copy functor connected to a signal each time the signal is emitted. Restoring the C++98 behavior. Task-number: QTBUG-52542 Change-Id: I3ca20ef6910893b8a288e70af7de4c7b69502173 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobjectdefs_impl.h | 2 +- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index d5574a4dd1..922b6bbb42 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -491,7 +491,7 @@ namespace QtPrivate { template struct FunctorCall; template struct FunctorCall, List, R, Function> { - static void call(Function f, void **arg) { + static void call(Function &f, void **arg) { f((*reinterpret_cast::Type *>(arg[II+1]))...), ApplyReturnValue(arg[0]); } }; diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index f3334b1222..5b89ef3792 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -147,6 +147,7 @@ private slots: void qmlConnect(); void exceptions(); void noDeclarativeParentChangedOnDestruction(); + void mutableFunctor(); }; struct QObjectCreatedOnShutdown @@ -6420,6 +6421,24 @@ void tst_QObject::noDeclarativeParentChangedOnDestruction() #endif } +struct MutableFunctor { + int count; + MutableFunctor() : count(0) {} + int operator()() { return ++count; } +}; + +void tst_QObject::mutableFunctor() +{ + ReturnValue o; + MutableFunctor functor; + QCOMPARE(functor.count, 0); + connect(&o, &ReturnValue::returnInt, functor); + QCOMPARE(emit o.returnInt(0), 1); + QCOMPARE(emit o.returnInt(0), 2); // each emit should increase the internal count + + QCOMPARE(functor.count, 0); // but the original object should have been copied at connect time +} + // Test for QtPrivate::HasQ_OBJECT_Macro Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro::Value); Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro::Value); -- cgit v1.2.3 From d8667fde189fa08002295fc66414d67e73b3c67b Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 8 Apr 2016 18:50:15 +0300 Subject: xcb: Fix interpretation of the size from RRCrtcChangeNotify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The size in RRCrtcChangeNotify is a size of the mode and it is not rotated. At the same time when we call RRGetCrtcInfo, it returns a rotated size, which is then passed to QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation). So to pass the expected size to QXcbScreen::updateGeometry() after receiving RRCrtcChangeNotify, we should rotate the size according the screen rotation. Change-Id: If5b5b52403b077d3cd64b9a05d938bb9ac00b1e0 Reviewed-by: Daniel Vrátil Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 05c02249cc..135c763dc1 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -209,6 +209,9 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) // CRTC with node mode could mean that output has been disabled, and we'll // get RRNotifyOutputChange notification for that. if (screen && crtc.mode) { + if (crtc.rotation == XCB_RANDR_ROTATION_ROTATE_90 || + crtc.rotation == XCB_RANDR_ROTATION_ROTATE_270) + std::swap(crtc.width, crtc.height); screen->updateGeometry(QRect(crtc.x, crtc.y, crtc.width, crtc.height), crtc.rotation); if (screen->mode() != crtc.mode) screen->updateRefreshRate(crtc.mode); -- cgit v1.2.3 From 1e229c7041dba1b1de401ed0beba163295653d98 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 11 Apr 2016 13:28:09 +0200 Subject: winrt: Cancel pending read operations before tcp sockets are closed According to the documentation tcp sockets are closed properly if their instances are deleted when no read operation is pending. Thus we have to keep track of the running read operation, cancel it (only available on Windows 10) and delete it before closing the socket. As there is no way to cancel the read operation on Windows 8.1 the hard reset still happens there. Change-Id: Idc75178f7d05057b610ac7000e95486d6a52cb85 Reviewed-by: Samuel Nevala Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 125 ++++++++++++++--------- src/network/socket/qnativesocketengine_winrt_p.h | 1 + 2 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 0ff76adecf..ce6788873f 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -395,28 +395,30 @@ int QNativeSocketEngine::accept() IStreamSocket *socket = d->pendingConnections.takeFirst(); HRESULT hr; - ComPtr buffer; - hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr stream; - hr = socket->get_InputStream(&stream); - Q_ASSERT_SUCCEEDED(hr); - ComPtr op; - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); - if (FAILED(hr)) { - qErrnoWarning(hr, "accept(): Failed to read from the socket buffer (%s).", - socketDescription(this).constData()); - return -1; - } - hr = QEventDispatcherWinRT::runOnXamlThread([d, op]() { - return op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() { + ComPtr buffer; + HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); + RETURN_HR_IF_FAILED("accept(): Could not create buffer"); + ComPtr stream; + hr = socket->get_InputStream(&stream); + RETURN_HR_IF_FAILED("accept(): Could not obtain input stream"); + hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &d->readOp); + if (FAILED(hr)) { + qErrnoWarning(hr, "accept(): Failed to read from the socket buffer (%s).", + socketDescription(this).constData()); + return E_FAIL; + } + hr = d->readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "accept(): Failed to set socket read callback (%s).", + socketDescription(this).constData()); + return E_FAIL; + } + return S_OK; }); - if (FAILED(hr)) { - qErrnoWarning(hr, "accept(): Failed to set socket read callback (%s).", - socketDescription(this).constData()); + if (hr == E_FAIL) return -1; - } + Q_ASSERT_SUCCEEDED(hr); d->currentConnections.append(socket); SocketHandler *handler = gSocketHandler(); @@ -454,6 +456,32 @@ void QNativeSocketEngine::close() } } +#if _MSC_VER >= 1900 + // To close the connection properly (not with a hard reset) all pending read operation have to + // be finished or cancelled. The API isn't available on Windows 8.1 though. + ComPtr socket3; + hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr action; + hr = socket3->CancelIOAsync(&action); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(action); + Q_ASSERT_SUCCEEDED(hr); +#endif // _MSC_VER >= 1900 + + if (d->readOp) { + ComPtr info; + hr = d->readOp.As(&info); + Q_ASSERT_SUCCEEDED(hr); + if (info) { + hr = info->Cancel(); + Q_ASSERT_SUCCEEDED(hr); + hr = info->Close(); + Q_ASSERT_SUCCEEDED(hr); + } + } + if (d->socketDescriptor != -1) { ComPtr socket; if (d->socketType == QAbstractSocket::TcpSocket) { @@ -784,17 +812,16 @@ void QNativeSocketEngine::establishRead() hr = QEventDispatcherWinRT::runOnXamlThread([d]() { ComPtr stream; HRESULT hr = d->tcpSocket()->get_InputStream(&stream); - RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to get socket input stream"); + RETURN_HR_IF_FAILED("establishRead(): Failed to get socket input stream"); ComPtr buffer; hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to create buffer"); + RETURN_HR_IF_FAILED("establishRead(): Failed to create buffer"); - ComPtr op; - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); - RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to initiate socket read"); - hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); - RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to register read callback"); + hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &d->readOp); + RETURN_HR_IF_FAILED("establishRead(): Failed to initiate socket read"); + hr = d->readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + RETURN_HR_IF_FAILED("establishRead(): Failed to register read callback"); return S_OK; }); Q_ASSERT_SUCCEEDED(hr); @@ -1294,31 +1321,33 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async if (notifyOnRead) emit q->readReady(); - ComPtr stream; - hr = tcpSocket()->get_InputStream(&stream); - Q_ASSERT_SUCCEEDED(hr); + hr = QEventDispatcherWinRT::runOnXamlThread([buffer, q, this]() { + UINT32 readBufferLength; + ComPtr stream; + HRESULT hr = tcpSocket()->get_InputStream(&stream); + RETURN_HR_IF_FAILED("handleReadyRead(): Could not obtain input stream"); - // Reuse the stream buffer - hr = buffer->get_Capacity(&bufferLength); - Q_ASSERT_SUCCEEDED(hr); - hr = buffer->put_Length(0); - Q_ASSERT_SUCCEEDED(hr); + // Reuse the stream buffer + hr = buffer->get_Capacity(&readBufferLength); + RETURN_HR_IF_FAILED("handleReadyRead(): Could not obtain buffer capacity"); + hr = buffer->put_Length(0); + RETURN_HR_IF_FAILED("handleReadyRead(): Could not set buffer length"); - ComPtr op; - hr = stream->ReadAsync(buffer.Get(), bufferLength, InputStreamOptions_Partial, &op); - if (FAILED(hr)) { - qErrnoWarning(hr, "handleReadyRead(): Could not read into socket stream buffer (%s).", - socketDescription(q).constData()); + hr = stream->ReadAsync(buffer.Get(), readBufferLength, InputStreamOptions_Partial, &readOp); + if (FAILED(hr)) { + qErrnoWarning(hr, "handleReadyRead(): Could not read into socket stream buffer (%s).", + socketDescription(q).constData()); + return S_OK; + } + hr = readOp->put_Completed(Callback(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).", + socketDescription(q).constData()); + return S_OK; + } return S_OK; - } - hr = QEventDispatcherWinRT::runOnXamlThread([op, this]() { - return op->put_Completed(Callback(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); }); - if (FAILED(hr)) { - qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).", - socketDescription(q).constData()); - return S_OK; - } + Q_ASSERT_SUCCEEDED(hr); return S_OK; } diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index c48b0e85d9..51793b278d 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -199,6 +199,7 @@ private: { return reinterpret_cast(socketDescriptor); } Microsoft::WRL::ComPtr tcpListener; Microsoft::WRL::ComPtr connectOp; + Microsoft::WRL::ComPtr> readOp; QBuffer readBytes; QMutex readMutex; -- cgit v1.2.3 From db051bc04fcd74362752dee891f2af3df197a4eb Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 7 Apr 2016 15:48:26 +0200 Subject: winrt: only emit readRead signal if the notifyOnRead flag is set Change-Id: Ie52ddc8b0f70ad64d8f503b1942b9da6b72d6c99 Reviewed-by: Samuel Nevala Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index ce6788873f..86198b809e 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -1197,7 +1197,8 @@ HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener args->get_Socket(&socket); pendingConnections.append(socket); emit q->connectionReady(); - emit q->readReady(); + if (notifyOnRead) + emit q->readReady(); return S_OK; } @@ -1381,7 +1382,8 @@ HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, I hr = reader->ReadBytes(length, reinterpret_cast(datagram.data.data())); RETURN_OK_IF_FAILED("Could not read datagram"); pendingDatagrams.append(datagram); - emit q->readReady(); + if (notifyOnRead) + emit q->readReady(); return S_OK; } -- cgit v1.2.3 From 29a8c2d9b9cc3055706cd022e5286f7b330fa55a Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 7 Apr 2016 15:49:16 +0200 Subject: winrt: Remove superfluous socketDescriptor assignment Change-Id: I567418f21eef2f07e0d5283f46a02305d1153e0a Reviewed-by: Samuel Nevala Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 86198b809e..21c5dc607a 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -499,7 +499,6 @@ void QNativeSocketEngine::close() if (socket) { hr = socket->Close(); Q_ASSERT_SUCCEEDED(hr); - d->socketDescriptor = -1; } d->socketDescriptor = -1; } -- cgit v1.2.3 From b501fc3b3378526e35590d1733ba61c7c1562a75 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 7 Apr 2016 15:52:59 +0200 Subject: winrt: Register for socket reads for correct socket engine Reading from the socket must not happen from the managing socket engine but the socket engines that are spawned for reading/writing data (these are initialized with the socket descriptor given). With the current implementation the managing socket engine might be closed after the first connection so that no other socket requests will be handled. Change-Id: I76e1356bb75b8641b4f113872be143ca5c8b08cc Reviewed-by: Samuel Nevala Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 61 +++++++++++++----------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 21c5dc607a..c5281ee9c5 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -239,7 +239,8 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket:: close(); // Currently, only TCP sockets are initialized this way. - d->socketDescriptor = qintptr(gSocketHandler->pendingTcpSockets.take(socketDescriptor)); + IStreamSocket *socket = gSocketHandler->pendingTcpSockets.take(socketDescriptor); + d->socketDescriptor = qintptr(socket); d->socketType = QAbstractSocket::TcpSocket; if (!d->socketDescriptor || !d->fetchConnectionParameters()) { @@ -249,6 +250,36 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket:: return false; } + // Start processing incoming data + if (d->socketType == QAbstractSocket::TcpSocket) { + HRESULT hr; + hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() { + ComPtr buffer; + HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); + RETURN_HR_IF_FAILED("initialize(): Could not create buffer"); + + ComPtr stream; + hr = socket->get_InputStream(&stream); + RETURN_HR_IF_FAILED("initialize(): Could not obtain input stream"); + hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, d->readOp.GetAddressOf()); + if (FAILED(hr)) { + qErrnoWarning(hr, "initialize(): Failed to read from the socket buffer (%s).", + socketDescription(this).constData()); + return E_FAIL; + } + hr = d->readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "initialize(): Failed to set socket read callback (%s).", + socketDescription(this).constData()); + return E_FAIL; + } + return S_OK; + }); + if (hr == E_FAIL) + return false; + Q_ASSERT_SUCCEEDED(hr); + } + d->socketState = socketState; return true; } @@ -390,37 +421,9 @@ int QNativeSocketEngine::accept() return -1; } - // Start processing incoming data if (d->socketType == QAbstractSocket::TcpSocket) { IStreamSocket *socket = d->pendingConnections.takeFirst(); - HRESULT hr; - hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() { - ComPtr buffer; - HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - RETURN_HR_IF_FAILED("accept(): Could not create buffer"); - ComPtr stream; - hr = socket->get_InputStream(&stream); - RETURN_HR_IF_FAILED("accept(): Could not obtain input stream"); - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &d->readOp); - if (FAILED(hr)) { - qErrnoWarning(hr, "accept(): Failed to read from the socket buffer (%s).", - socketDescription(this).constData()); - return E_FAIL; - } - hr = d->readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); - if (FAILED(hr)) { - qErrnoWarning(hr, "accept(): Failed to set socket read callback (%s).", - socketDescription(this).constData()); - return E_FAIL; - } - return S_OK; - }); - if (hr == E_FAIL) - return -1; - Q_ASSERT_SUCCEEDED(hr); - d->currentConnections.append(socket); - SocketHandler *handler = gSocketHandler(); handler->pendingTcpSockets.insert(++handler->socketCount, socket); return handler->socketCount; -- cgit v1.2.3 From 208f364a953146223fe5cb41ca44875f4c85cdd9 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 11 Apr 2016 13:32:24 +0200 Subject: WinRT: Removed superfluous callback that handles completed binds The callback was added as the functionality did not work as expected on Windows 8. The behavior seems to have been fixed so that the callback is no longer needed and can be removed. Change-Id: I3def5750271e40eea1c6a88eed693f4da4ea44bb Reviewed-by: Samuel Nevala Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 7 ------- src/network/socket/qnativesocketengine_winrt_p.h | 1 - 2 files changed, 8 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index c5281ee9c5..599f37929c 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -383,8 +383,6 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) } RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Unable to bind socket"); - hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); - RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not register bind callback"); hr = QWinRTFunctions::await(op); RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not wait for bind to finish"); return S_OK; @@ -1186,11 +1184,6 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() return true; } -HRESULT QNativeSocketEnginePrivate::handleBindCompleted(IAsyncAction *, AsyncStatus) -{ - return S_OK; -} - HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener *listener, IStreamSocketListenerConnectionReceivedEventArgs *args) { Q_Q(QNativeSocketEngine); diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 51793b278d..4a5bc81769 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -210,7 +210,6 @@ private: QAbstractSocket *sslSocket; EventRegistrationToken connectionToken; - HRESULT handleBindCompleted(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); HRESULT handleNewDatagram(ABI::Windows::Networking::Sockets::IDatagramSocket *socket, ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *args); HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, -- cgit v1.2.3 From 96ff51f856c34c7826c13c2d4c376022e6b7d027 Mon Sep 17 00:00:00 2001 From: MATSUMURA Tetsuro Date: Wed, 13 Apr 2016 20:35:45 +0900 Subject: Fix dependency scanner being confused by UTF-8 BOM Update QMakeSourceFileInfo::findDeps to skip UTF-8 BOM if exists. Task-number: QTBUG-34182 Change-Id: I7a3e30ecab08f485c53e2ca2eab197619b11c2c7 Reviewed-by: Edward Welbourne Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefiledeps.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp index 047d17f18a..ae81ebc1db 100644 --- a/qmake/generators/makefiledeps.cpp +++ b/qmake/generators/makefiledeps.cpp @@ -554,7 +554,14 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file) InCode // after directive, parsing non-#include directive or in actual code } cpp_state = AtStart; - for(int x = 0; x < buffer_len; ++x) { + int x = 0; + if (buffer_len >= 3) { + const unsigned char *p = (unsigned char *)buffer; + // skip UTF-8 BOM, if present + if (p[0] == 0xEF && p[1] == 0xBB && p[2] == 0xBF) + x += 3; + } + for (; x < buffer_len; ++x) { bool try_local = true; char *inc = 0; if(file->type == QMakeSourceFileInfo::TYPE_UI) { -- cgit v1.2.3 From 17ad6e2a93f93aaa948c1286b3cad785e7f38808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 13 Apr 2016 14:09:35 +0200 Subject: Fix build when Qt is used in an automatic reference-counted environment When automatic reference-counting (ARC) is enabled on Darwin platforms the NSAutoReleasePool class should not be used directly, which caused a build error if qglobal.h was included after the Foundation.h in client code. The preferred alternative for ARC is the scoped @autoreleasepool construct, which allows the compiler to reason about needing to insert _objc_autoreleasePoolPush and _objc_autoreleasePoolPop calls. Note that ARC translation units can be combined with non-ARC translation units, so Qt and the QMacAutoReleasePool class can still be used in ARC client code even if Qt is not built with ARC. Task-number: QTBUG-51332 Change-Id: I7ef1c3146aa416a9d6a1dc299ce7b17f22f889e5 Reviewed-by: Simon Hausmann Reviewed-by: Richard Moe Gustavsen --- src/corelib/global/qglobal.h | 6 +----- src/corelib/kernel/qcore_mac_objc.mm | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 98c9902674..5bb1ce77bd 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -579,10 +579,6 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max # define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) \ QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, __IPHONE_NA) -QT_END_NAMESPACE -Q_FORWARD_DECLARE_OBJC_CLASS(NSAutoreleasePool); -QT_BEGIN_NAMESPACE - // Implemented in qcore_mac_objc.mm class Q_CORE_EXPORT QMacAutoReleasePool { @@ -591,7 +587,7 @@ public: ~QMacAutoReleasePool(); private: Q_DISABLE_COPY(QMacAutoReleasePool) - NSAutoreleasePool *pool; + void *pool; }; #endif // Q_OS_MAC diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 1a2b047041..e1480a36d5 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -150,7 +150,7 @@ QMacAutoReleasePool::~QMacAutoReleasePool() // Drain behaves the same as release, with the advantage that // if we're ever used in a garbage-collected environment, the // drain acts as a hint to the garbage collector to collect. - [pool drain]; + [static_cast(pool) drain]; } // ------------------------------------------------------------------------- -- cgit v1.2.3 From b808c0099ac5880ef06f419c1017146ce40953d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 13 Apr 2016 17:09:06 +0200 Subject: OS X: Fix available geometry at startup when menu bar is hidden Later versions of OS X allow you to auto-hide the menu bar, which should free up 22 pixels vertically at the top of the screen in the available geometry. Due to how the NSScreens are invalidated (asynchronously), we pick up this geometry change too late, resulting in QWindows maximizing as if the menu bar was still there. To work around this we explicitly tell the system to apply the default presentation options before initializing the QScreen properties, which results in the NSScreen being invalidated synchronously and having the right available geometry. Change-Id: I40d6ef2211165d53e0825173e3b6c6c17a5a954e Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 91d4b2706b..933160b2ca 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -331,6 +331,15 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) [newDelegate setMenuLoader:qtMenuLoader]; } + // The presentation options such as whether or not the dock and/or menu bar is + // hidden (automatically by the system) affects the main screen's available + // geometry. Since we're initializing the screens synchronously at application + // startup we need to ensure that the presentation options have been propagated + // to the screen before we read out its properties. Normally OS X does this in + // an asynchronous callback, but that's too late for us. We force the propagation + // by explicitly setting the presentation option to the magic 'default value', + // which will resolve to an actual value and result in screen invalidation. + cocoaApplication.presentationOptions = NSApplicationPresentationDefault; updateScreens(); QMacInternalPasteboardMime::initializeMimeTypes(); -- cgit v1.2.3 From f494da8895fa7a28dbc9ff0a66235632c8c33167 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 3 Jan 2016 00:15:47 -0200 Subject: Clang 3.8 is clean of warnings Change-Id: Ibc83b9f7e3bc4962ae35ffff1425c8e686579e15 Reviewed-by: Jake Petroules --- mkspecs/features/qt_common.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index e70d3bf172..cc8ed87b90 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -50,10 +50,10 @@ warnings_are_errors:warning_clean { # compiler. clang:!ios { # Apple clang 4.0-4.2,5.0-5.1,6.0-6.4 - # Regular clang 3.3-3.7 + # Regular clang 3.3-3.8 apple_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION} reg_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION} - contains(apple_ver, "4\\.[012]|5\\.[01]|6\\.[01234]")|contains(reg_ver, "3\\.[3-7]") { + contains(apple_ver, "4\\.[012]|5\\.[01]|6\\.[01234]")|contains(reg_ver, "3\\.[3-8]") { QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR } } else:intel_icc:linux { -- cgit v1.2.3 From 5b37c9f7d3153a756af8fa89b2467c87a3021a8b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Apr 2016 13:35:30 -0700 Subject: Work around Clang false-positive warning on returning default parameters Clang 3.8 and Apple Clang 7.x seem to think that the parameter is a temporary. See https://llvm.org/bugs/show_bug.cgi?id=26396 Task-number: QTBUG-52134 Change-Id: Id75834dab9ed466e94c7ffff1444b6f2424d7fb7 Reviewed-by: Jake Petroules --- src/corelib/tools/qmap.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index fe9ddaaa32..ed49e70f4e 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -634,6 +634,8 @@ Q_INLINE_TEMPLATE void QMap::clear() *this = QMap(); } +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wreturn-stack-address") template Q_INLINE_TEMPLATE const T QMap::value(const Key &akey, const T &adefaultValue) const @@ -642,6 +644,8 @@ Q_INLINE_TEMPLATE const T QMap::value(const Key &akey, const T &adefault return n ? n->value : adefaultValue; } +QT_WARNING_POP + template Q_INLINE_TEMPLATE const T QMap::operator[](const Key &akey) const { -- cgit v1.2.3 From 7ab0829823024dd07d15ff6786e3648388d4f28d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Apr 2016 13:38:18 -0700 Subject: Fix parsing of empty port sections in URLs The RFC does allow it. It even has examples showing them as valid. In section 6.2.3, it shows: http://example.com http://example.com/ http://example.com:/ http://example.com:80/ Change-Id: Id75834dab9ed466e94c7ffff1444b7195ad21cab Reviewed-by: Frederik Gladhorn Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/corelib/io/qurl.cpp | 2 +- tests/auto/corelib/io/qurl/tst_qurl.cpp | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index b51119c7ad..b27321b2a6 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1046,7 +1046,7 @@ inline void QUrlPrivate::setAuthority(const QString &auth, int from, int end, QU if (colonIndex == end - 1) { // found a colon but no digits after it - setError(PortEmptyError, auth, colonIndex + 1); + port = -1; } else if (uint(colonIndex) < uint(end)) { unsigned long x = 0; for (int i = colonIndex + 1; i < end; ++i) { diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index b284e5fc9c..eba058a13c 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -148,6 +148,8 @@ private slots: void hostFlags_data(); void hostFlags(); void setPort(); + void port_data(); + void port(); void toEncoded_data(); void toEncoded(); void setAuthority_data(); @@ -2205,8 +2207,6 @@ void tst_QUrl::strictParser_data() // FIXME: add some tests for prohibited BiDi (RFC 3454 section 6) // port errors happen in TolerantMode too - QTest::newRow("empty-port-1") << "http://example.com:" << "Port field was empty"; - QTest::newRow("empty-port-2") << "http://example.com:/" << "Port field was empty"; QTest::newRow("invalid-port-1") << "http://example.com:-1" << "Invalid port"; QTest::newRow("invalid-port-2") << "http://example.com:abc" << "Invalid port"; QTest::newRow("invalid-port-3") << "http://example.com:9a" << "Invalid port"; @@ -2783,6 +2783,31 @@ void tst_QUrl::setPort() } } +void tst_QUrl::port_data() +{ + QTest::addColumn("input"); + QTest::addColumn("port"); + + QTest::newRow("no-port-1") << "http://example.com" << -1; + QTest::newRow("no-port-2") << "http://example.com/" << -1; + QTest::newRow("empty-port-1") << "http://example.com:" << -1; + QTest::newRow("empty-port-2") << "http://example.com:/" << -1; + QTest::newRow("zero-port-1") << "http://example.com:0" << 0; + QTest::newRow("zero-port-2") << "http://example.com:0/" << 0; + QTest::newRow("set-port-1") << "http://example.com:80" << 80; + QTest::newRow("set-port-2") << "http://example.com:80/" << 80; +} + +void tst_QUrl::port() +{ + QFETCH(QString, input); + QFETCH(int, port); + + QUrl url(input); + QVERIFY(url.isValid()); + QCOMPARE(url.port(), port); +} + void tst_QUrl::toEncoded_data() { QTest::addColumn("url"); -- cgit v1.2.3 From 77fb9ca271e515f6a147d3dc7025bf3501c70fa0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Apr 2016 14:46:04 -0700 Subject: Fix encoding of IDN hostnames with QUrl::host When the formatting parameter wasn't exactly QUrl::EncodeUnicode, it wouldn't encode, despite having to. Change-Id: Id75834dab9ed466e94c7ffff1444bacc08dd109b Reviewed-by: Frederik Gladhorn Reviewed-by: Edward Welbourne --- src/corelib/io/qurl.cpp | 2 +- tests/auto/corelib/io/qurl/tst_qurl.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index b27321b2a6..fb2f4ba918 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1176,7 +1176,7 @@ inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions o } else { // this is either an IPv4Address or a reg-name // if it is a reg-name, it is already stored in Unicode form - if (options == QUrl::EncodeUnicode) + if (options & QUrl::EncodeUnicode && !(options & 0x4000000)) appendTo += qt_ACE_do(host, ToAceOnly, AllowLeadingDot); else appendTo += host; diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index eba058a13c..ef210d4a64 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -1749,6 +1749,9 @@ void tst_QUrl::symmetry() QUrl url(QString::fromUtf8("http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl")); QCOMPARE(url.scheme(), QString::fromLatin1("http")); QCOMPARE(url.host(), QString::fromUtf8("www.räksmörgås.se")); + QCOMPARE(url.host(QUrl::EncodeSpaces), QString::fromUtf8("www.räksmörgås.se")); + QCOMPARE(url.host(QUrl::EncodeUnicode), QString::fromUtf8("www.xn--rksmrgs-5wao1o.se")); + QCOMPARE(url.host(QUrl::EncodeUnicode | QUrl::EncodeSpaces), QString::fromUtf8("www.xn--rksmrgs-5wao1o.se")); QCOMPARE(url.path(), QString::fromLatin1("/pub")); // this will be encoded ... QCOMPARE(url.encodedQuery().constData(), QString::fromLatin1("a=b&a=d%C3%B8&a=f").toLatin1().constData()); -- cgit v1.2.3 From 479a791ab2696d5c5571c99d1313681dd12d40d0 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 13 Apr 2016 13:03:12 +0200 Subject: Fix QSysInfo::windowsVersion() on WinCE Use the GetVersionEx method on WinCE. The ntdll.dll does not exist on that platform, therefor a wrong version number was returned. Change-Id: I7b51757d0fb612dcd8832e0903a93b9d1c6746c0 Reviewed-by: Friedemann Kleint Reviewed-by: Andreas Holzammer --- src/corelib/global/qglobal.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 461b0f383d..77724d2a0d 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1940,6 +1940,7 @@ static inline OSVERSIONINFO winOsVersion() #define pGetModuleHandle GetModuleHandleW #endif +#ifndef Q_OS_WINCE HMODULE ntdll = pGetModuleHandle(L"ntdll.dll"); if (Q_UNLIKELY(!ntdll)) return result; @@ -1959,6 +1960,10 @@ static inline OSVERSIONINFO winOsVersion() // GetVersionEx() has been deprecated in Windows 8.1 and will return // only Windows 8 from that version on, so use the kernel API function. pRtlGetVersion(&result); // always returns STATUS_SUCCESS +#else // !Q_OS_WINCE + GetVersionEx(&result); +#endif + return result; } -- cgit v1.2.3 From 62ad5abe0637abc742f10cc31a3faf0a2353ab2f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 14 Apr 2016 10:00:24 +0200 Subject: QWinEventNotifier: compile with -Wzero-as-null-pointer-constant Seems to be the last 5.6 QtBase public header that didn't, paving the way to add the warning to the headersclean check. Change-Id: Ib2655782e34ec58e5d9b1b9c0ec31a965a38f9b7 Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qwineventnotifier.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qwineventnotifier.h b/src/corelib/kernel/qwineventnotifier.h index 95fdff07ce..f59754de6f 100644 --- a/src/corelib/kernel/qwineventnotifier.h +++ b/src/corelib/kernel/qwineventnotifier.h @@ -48,8 +48,8 @@ class Q_CORE_EXPORT QWinEventNotifier : public QObject typedef Qt::HANDLE HANDLE; public: - explicit QWinEventNotifier(QObject *parent = 0); - explicit QWinEventNotifier(HANDLE hEvent, QObject *parent = 0); + explicit QWinEventNotifier(QObject *parent = Q_NULLPTR); + explicit QWinEventNotifier(HANDLE hEvent, QObject *parent = Q_NULLPTR); ~QWinEventNotifier(); void setHandle(HANDLE hEvent); -- cgit v1.2.3 From ab599a39313c22fd14cc5466cea5c61bbcdbba8e Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Wed, 6 Apr 2016 20:37:44 -0700 Subject: qmake: Add support for separate debug info on Apple platforms. This makes the -separate-debug-info configure optional functional, which generates dSYM debug info bundles for Qt libraries on Apple platforms. Task-number: QTBUG-37952 Done-with: Oswald Buddenhagen Change-Id: Ia247674740bf450130a15db926df07fa9007e2ca Reviewed-by: Oswald Buddenhagen --- configure | 2 +- mkspecs/common/mac.conf | 3 + mkspecs/features/unix/separate_debug_info.prf | 80 +++++++++++++++++++++------ mkspecs/macx-clang-32/Info.plist.dSYM.in | 18 ++++++ mkspecs/macx-clang/Info.plist.dSYM.in | 18 ++++++ mkspecs/macx-g++-32/Info.plist.dSYM.in | 18 ++++++ mkspecs/macx-g++/Info.plist.dSYM.in | 18 ++++++ mkspecs/macx-g++40/Info.plist.dSYM.in | 18 ++++++ mkspecs/macx-g++42/Info.plist.dSYM.in | 18 ++++++ mkspecs/macx-icc/Info.plist.dSYM.in | 18 ++++++ mkspecs/macx-ios-clang/Info.plist.dSYM.in | 18 ++++++ mkspecs/macx-llvm/Info.plist.dSYM.in | 18 ++++++ 12 files changed, 230 insertions(+), 17 deletions(-) create mode 100644 mkspecs/macx-clang-32/Info.plist.dSYM.in create mode 100644 mkspecs/macx-clang/Info.plist.dSYM.in create mode 100644 mkspecs/macx-g++-32/Info.plist.dSYM.in create mode 100644 mkspecs/macx-g++/Info.plist.dSYM.in create mode 100644 mkspecs/macx-g++40/Info.plist.dSYM.in create mode 100644 mkspecs/macx-g++42/Info.plist.dSYM.in create mode 100644 mkspecs/macx-icc/Info.plist.dSYM.in create mode 100644 mkspecs/macx-ios-clang/Info.plist.dSYM.in create mode 100644 mkspecs/macx-llvm/Info.plist.dSYM.in diff --git a/configure b/configure index 1cafa98c3b..3e97c98e1a 100755 --- a/configure +++ b/configure @@ -4362,7 +4362,7 @@ fi #------------------------------------------------------------------------------- # Detect objcopy support -if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then +if [ "$XPLATFORM_MAC" = "no" ] && [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then if ! compileTest unix/objcopy "objcopy"; then echo "ERROR: -separate-debug-info was requested but this binutils does not support it." echo "Re-run configure with -v for more information" diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index ad3c638a6f..aac9d1b3d7 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -29,6 +29,9 @@ QMAKE_LIBS_DYNLOAD = QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL QMAKE_LIBS_THREAD = +QMAKE_DSYMUTIL = dsymutil +QMAKE_STRIP = strip + QMAKE_AR = ar cq QMAKE_RANLIB = ranlib -s QMAKE_NM = nm -P diff --git a/mkspecs/features/unix/separate_debug_info.prf b/mkspecs/features/unix/separate_debug_info.prf index 7d9022f8d7..460ad63e22 100644 --- a/mkspecs/features/unix/separate_debug_info.prf +++ b/mkspecs/features/unix/separate_debug_info.prf @@ -1,29 +1,77 @@ - -have_target:!static:!isEmpty(QMAKE_OBJCOPY) { - qnx { - debug_info_suffix = sym - debug_info_keep = --keep-file-symbols - debug_info_strip = --strip-debug -R.ident +have_target:!static:if(darwin|!isEmpty(QMAKE_OBJCOPY)) { + darwin { + debug_info_copy_bin = $$QMAKE_DSYMUTIL + debug_info_strip_bin = $$QMAKE_STRIP + debug_info_suffix = dSYM + debug_info_out = --flat -o + debug_info_strip = -S } else { - debug_info_suffix = debug - debug_info_keep = --only-keep-debug - debug_info_strip = --strip-debug + debug_info_copy_bin = $$QMAKE_OBJCOPY + debug_info_strip_bin = $$QMAKE_OBJCOPY + qnx { + debug_info_suffix = sym + debug_info_keep = --keep-file-symbols + debug_info_strip = --strip-debug -R.ident + } else { + debug_info_suffix = debug + debug_info_keep = --only-keep-debug + debug_info_strip = --strip-debug + } } load(resolve_target) - QMAKE_TARGET_DEBUG_INFO = $${QMAKE_RESOLVED_TARGET}.$$debug_info_suffix + debug_info_target = $$QMAKE_RESOLVED_TARGET + + darwin { + !isEmpty(QMAKE_RESOLVED_BUNDLE) { + debug_info_target = $$QMAKE_RESOLVED_BUNDLE + CONFIG += any_bundle + } + + debug_info_target_dir = $${debug_info_target}.$$debug_info_suffix/Contents/Resources/DWARF + !isEmpty(QMAKE_RESOLVED_BUNDLE): \ + QMAKE_TARGET_DEBUG_INFO = $$debug_info_target_dir/$$TARGET + else: \ + QMAKE_TARGET_DEBUG_INFO = $$debug_info_target_dir/$$section(QMAKE_RESOLVED_TARGET, /, -1, -1) + + if(any_bundle:!build_pass)|if(!any_bundle:if(build_pass|isEmpty(BUILDS))) { + equals(TEMPLATE, lib):lib_bundle:!isEmpty(QMAKE_FRAMEWORK_BUNDLE_NAME): \ + BUNDLEIDENTIFIER = $$replace(QMAKE_FRAMEWORK_BUNDLE_NAME, \\.framework$, ) + else: equals(TEMPLATE, app):app_bundle:!isEmpty(QMAKE_APPLICATION_BUNDLE_NAME): \ + BUNDLEIDENTIFIER = $$replace(QMAKE_APPLICATION_BUNDLE_NAME, \\.app$, ) + else: \ + BUNDLEIDENTIFIER = $${TARGET} + + !isEmpty(QMAKE_TARGET_BUNDLE_PREFIX): \ + BUNDLEIDENTIFIER = $$replace(QMAKE_TARGET_BUNDLE_PREFIX, \\.$, ).$${BUNDLEIDENTIFIER} + else: \ + BUNDLEIDENTIFIER = com.yourcompany.$${BUNDLEIDENTIFIER} + + BUNDLEIDENTIFIER ~= s,_,-, + + debug_info_plist.input = $$QMAKESPEC/Info.plist.dSYM.in + debug_info_plist.output = $${debug_info_target}.$$debug_info_suffix/Contents/Info.plist + QMAKE_SUBSTITUTES += debug_info_plist + } + } else { + QMAKE_TARGET_DEBUG_INFO = $${QMAKE_RESOLVED_TARGET}.$$debug_info_suffix + } shell_target = $$shell_quote($$relative_path($$QMAKE_RESOLVED_TARGET, $$OUT_PWD)) shell_target_debug_info = $$shell_quote($$relative_path($$QMAKE_TARGET_DEBUG_INFO, $$OUT_PWD)) - copy_debug_info = $$QMAKE_OBJCOPY $$debug_info_keep $$shell_target $$shell_target_debug_info - strip_debug_info = $$QMAKE_OBJCOPY $$debug_info_strip $$shell_target - link_debug_info = $$QMAKE_OBJCOPY --add-gnu-debuglink=$$shell_target_debug_info $$shell_target - chmod_debug_info = chmod -x $$shell_target_debug_info + copy_debug_info = $$debug_info_copy_bin $$debug_info_keep $$shell_target $$debug_info_out $$shell_target_debug_info + strip_debug_info = $$debug_info_strip_bin $$debug_info_strip $$shell_target !isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK - QMAKE_POST_LINK = $$copy_debug_info && $$strip_debug_info && $$link_debug_info && $$chmod_debug_info $$QMAKE_POST_LINK + darwin { + mkdir_debug_info = $$QMAKE_MKDIR $$shell_quote($$debug_info_target_dir) + QMAKE_POST_LINK = $$mkdir_debug_info && $$copy_debug_info && $$strip_debug_info $$QMAKE_POST_LINK + } else { + link_debug_info = $$QMAKE_OBJCOPY --add-gnu-debuglink=$$shell_target_debug_info $$shell_target + chmod_debug_info = chmod -x $$shell_target_debug_info + QMAKE_POST_LINK = $$copy_debug_info && $$strip_debug_info && $$link_debug_info && $$chmod_debug_info $$QMAKE_POST_LINK + } silent:QMAKE_POST_LINK = @echo creating $@.$$debug_info_suffix && $$QMAKE_POST_LINK target.targets += $$QMAKE_TARGET_DEBUG_INFO QMAKE_DISTCLEAN += $$QMAKE_TARGET_DEBUG_INFO } - diff --git a/mkspecs/macx-clang-32/Info.plist.dSYM.in b/mkspecs/macx-clang-32/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-clang-32/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + diff --git a/mkspecs/macx-clang/Info.plist.dSYM.in b/mkspecs/macx-clang/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-clang/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + diff --git a/mkspecs/macx-g++-32/Info.plist.dSYM.in b/mkspecs/macx-g++-32/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-g++-32/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + diff --git a/mkspecs/macx-g++/Info.plist.dSYM.in b/mkspecs/macx-g++/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-g++/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + diff --git a/mkspecs/macx-g++40/Info.plist.dSYM.in b/mkspecs/macx-g++40/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-g++40/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + diff --git a/mkspecs/macx-g++42/Info.plist.dSYM.in b/mkspecs/macx-g++42/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-g++42/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + diff --git a/mkspecs/macx-icc/Info.plist.dSYM.in b/mkspecs/macx-icc/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-icc/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + diff --git a/mkspecs/macx-ios-clang/Info.plist.dSYM.in b/mkspecs/macx-ios-clang/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-ios-clang/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + diff --git a/mkspecs/macx-llvm/Info.plist.dSYM.in b/mkspecs/macx-llvm/Info.plist.dSYM.in new file mode 100644 index 0000000000..a8c8d0d4fb --- /dev/null +++ b/mkspecs/macx-llvm/Info.plist.dSYM.in @@ -0,0 +1,18 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.$${BUNDLEIDENTIFIER} + CFBundlePackageType + dSYM + CFBundleSignature + ???? +!!IF !isEmpty(VERSION) + CFBundleShortVersionString + $${VER_MAJ}.$${VER_MIN} + CFBundleVersion + $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} +!!ENDIF + + -- cgit v1.2.3 From 540681749388e9b2ca775914faed27b936776978 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Tue, 12 Apr 2016 15:24:09 -0700 Subject: Fix separate_debug_info with no_plugin_name_prefix Task-number: QTBUG-51782 Change-Id: I5499139c732f2ff474095e30bc1f7a22743f4b12 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/resolve_target.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/resolve_target.prf b/mkspecs/features/resolve_target.prf index 5c3a46e117..629a02a4f3 100644 --- a/mkspecs/features/resolve_target.prf +++ b/mkspecs/features/resolve_target.prf @@ -28,7 +28,7 @@ win32 { } QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${TARGET}$${TARGET_VERSION_EXT}$${TARGET_EXT} } else { - contains(TEMPLATE, .*lib):LIBPREFIX = lib + contains(TEMPLATE, .*lib):!if(plugin:no_plugin_name_prefix): LIBPREFIX = lib mac { equals(TEMPLATE, lib) { -- cgit v1.2.3 From 152e496cdac8529fea53ed1006851546203a60b7 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 13 Apr 2016 16:33:25 +0200 Subject: Avoid conversion warnings in qrgba64.h Make implicit down conversions explicit to silence the most pedantic of compiler warnings. Task-number: QTBUG-52545 Change-Id: Id8f9574b47c8b4ee43023c80a3e009fab0e85008 Reviewed-by: Friedemann Kleint --- src/gui/painting/qrgba64.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/gui/painting/qrgba64.h b/src/gui/painting/qrgba64.h index fab9506ff2..413315f12a 100644 --- a/src/gui/painting/qrgba64.h +++ b/src/gui/painting/qrgba64.h @@ -97,7 +97,7 @@ public: Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromArgb32(uint rgb) { - return fromRgba(rgb >> 16, rgb >> 8, rgb, rgb >> 24); + return fromRgba(quint8(rgb >> 16), quint8(rgb >> 8), quint8(rgb), quint8(rgb >> 24)); } Q_DECL_CONSTEXPR bool isOpaque() const @@ -109,10 +109,10 @@ public: return (rgba & alphaMask()) == 0; } - Q_DECL_CONSTEXPR quint16 red() const { return rgba >> RedShift; } - Q_DECL_CONSTEXPR quint16 green() const { return rgba >> GreenShift; } - Q_DECL_CONSTEXPR quint16 blue() const { return rgba >> BlueShift; } - Q_DECL_CONSTEXPR quint16 alpha() const { return rgba >> AlphaShift; } + Q_DECL_CONSTEXPR quint16 red() const { return quint16(rgba >> RedShift); } + Q_DECL_CONSTEXPR quint16 green() const { return quint16(rgba >> GreenShift); } + Q_DECL_CONSTEXPR quint16 blue() const { return quint16(rgba >> BlueShift); } + Q_DECL_CONSTEXPR quint16 alpha() const { return quint16(rgba >> AlphaShift); } void setRed(quint16 _red) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << RedShift)) | (quint64(_red) << RedShift); } void setGreen(quint16 _green) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << GreenShift)) | (quint64(_green) << GreenShift); } void setBlue(quint16 _blue) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << BlueShift)) | (quint64(_blue) << BlueShift); } @@ -124,11 +124,11 @@ public: Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(alpha()); } Q_DECL_CONSTEXPR uint toArgb32() const { - return (alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8(); + return uint((alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8()); } Q_DECL_CONSTEXPR ushort toRgb16() const { - return (red() & 0xf800) | ((green() >> 10) << 5) | (blue() >> 11); + return ushort((red() & 0xf800) | ((green() >> 10) << 5) | (blue() >> 11)); } Q_DECL_RELAXED_CONSTEXPR QRgba64 premultiplied() const @@ -137,7 +137,7 @@ public: const quint16 r = div_65535(red() * a); const quint16 g = div_65535(green() * a); const quint16 b = div_65535(blue() * a); - return fromRgba64(r, g, b, a); + return fromRgba64(r, g, b, quint16(a)); } Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied() const @@ -163,18 +163,18 @@ public: private: static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint64 alphaMask() { return Q_UINT64_C(0xffff) << AlphaShift; } - static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint div_257_floor(uint x) { return (x - (x >> 8)) >> 8; } - static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint div_257(uint x) { return div_257_floor(x + 128); } - static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; } + static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint8 div_257_floor(uint x) { return quint8((x - (x >> 8)) >> 8); } + static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint8 div_257(quint16 x) { return div_257_floor(x + 128U); } + static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint16 div_65535(uint x) { return quint16((x + (x>>16) + 0x8000U) >> 16); } Q_DECL_RELAXED_CONSTEXPR Q_ALWAYS_INLINE QRgba64 unpremultiplied_32bit() const { if (isOpaque() || isTransparent()) return *this; const quint32 a = alpha(); - const quint16 r = (quint32(red()) * 0xffff + a/2) / a; - const quint16 g = (quint32(green()) * 0xffff + a/2) / a; - const quint16 b = (quint32(blue()) * 0xffff + a/2) / a; - return fromRgba64(r, g, b, a); + const quint16 r = quint16((red() * 0xffff + a/2) / a); + const quint16 g = quint16((green() * 0xffff + a/2) / a); + const quint16 b = quint16((blue() * 0xffff + a/2) / a); + return fromRgba64(r, g, b, quint16(a)); } Q_DECL_RELAXED_CONSTEXPR Q_ALWAYS_INLINE QRgba64 unpremultiplied_64bit() const { @@ -182,10 +182,10 @@ private: return *this; const quint64 a = alpha(); const quint64 fa = (Q_UINT64_C(0xffff00008000) + a/2) / a; - const quint16 r = (red() * fa + 0x80000000) >> 32; - const quint16 g = (green() * fa + 0x80000000) >> 32; - const quint16 b = (blue() * fa + 0x80000000) >> 32; - return fromRgba64(r, g, b, a); + const quint16 r = quint16((red() * fa + 0x80000000) >> 32); + const quint16 g = quint16((green() * fa + 0x80000000) >> 32); + const quint16 b = quint16((blue() * fa + 0x80000000) >> 32); + return fromRgba64(r, g, b, quint16(a)); } }; -- cgit v1.2.3 From 1ce52b0ddd71e7029f67fb91166783a0c09d25c6 Mon Sep 17 00:00:00 2001 From: Jochen Seemann Date: Thu, 24 Mar 2016 15:22:05 +0100 Subject: winrt: use visible bounds the get the visual area On Windows Phone / Windows 10 Mobile, there are the status bar and sometimes a navigation bar, which are hiding the visible window area. In the Windows Phone code paths, the area of the status bar was tracked and the visual area was dynamically shrinked. This patch enables that we use ApplicationView::visibleBounds() on every target (except Windows 8.1) to get the visible area of the application. Its change event is now also used as a resize trigger for manual resizing through user. Task-number: QTBUG-51163 Change-Id: I7abe2a0978418cc941e118e212426852474c026a Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 191 ++++++++++----------------- src/plugins/platforms/winrt/qwinrtscreen.h | 18 +-- src/plugins/platforms/winrt/qwinrtwindow.cpp | 4 - 3 files changed, 74 insertions(+), 139 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index fbf6393d90..ad89cb005c 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -85,9 +85,9 @@ typedef ITypedEventHandler PointerHandler; typedef ITypedEventHandler SizeChangedHandler; typedef ITypedEventHandler VisibilityChangedHandler; typedef ITypedEventHandler DisplayInformationHandler; -#ifdef Q_OS_WINPHONE -typedef ITypedEventHandler StatusBarHandler; -#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +typedef ITypedEventHandler VisibleBoundsChangedHandler; +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) QT_BEGIN_NAMESPACE @@ -448,10 +448,10 @@ typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistr uint qHash(CoreWindowCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRegistrationToken); uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } -#ifdef Q_OS_WINPHONE -typedef HRESULT (__stdcall IStatusBar::*StatusBarCallbackRemover)(EventRegistrationToken); -uint qHash(StatusBarCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } -#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +typedef HRESULT (__stdcall IApplicationView2::*ApplicationView2CallbackRemover)(EventRegistrationToken); +uint qHash(ApplicationView2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) class QWinRTScreenPrivate { @@ -461,13 +461,11 @@ public: ComPtr canvas; ComPtr view; ComPtr displayInformation; -#ifdef Q_OS_WINPHONE - ComPtr statusBar; -#endif QScopedPointer cursor; QHash touchPoints; - QSizeF logicalSize; + QRectF logicalRect; + QRectF visibleRect; QSurfaceFormat surfaceFormat; qreal logicalDpi; QDpi physicalDpi; @@ -478,9 +476,10 @@ public: QHash activeKeys; QHash windowTokens; QHash displayTokens; -#ifdef Q_OS_WINPHONE - QHash statusBarTokens; -#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + QHash view2Tokens; + ComPtr view2; +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) }; // To be called from the XAML thread @@ -511,7 +510,8 @@ QWinRTScreen::QWinRTScreen() Rect rect; hr = d->coreWindow->get_Bounds(&rect); Q_ASSERT_SUCCEEDED(hr); - d->logicalSize = QSizeF(rect.Width, rect.Height); + d->logicalRect = QRectF(0.0f, 0.0f, rect.Width, rect.Height); + d->visibleRect = QRectF(0.0f, 0.0f, rect.Width, rect.Height); // Orientation handling ComPtr displayInformationStatics; @@ -546,9 +546,9 @@ QWinRTScreen::QWinRTScreen() ComPtr frameworkElement; hr = canvas.As(&frameworkElement); Q_ASSERT_SUCCEEDED(hr); - hr = frameworkElement->put_Width(d->logicalSize.width()); + hr = frameworkElement->put_Width(d->logicalRect.width()); Q_ASSERT_SUCCEEDED(hr); - hr = frameworkElement->put_Height(d->logicalSize.height()); + hr = frameworkElement->put_Height(d->logicalRect.height()); Q_ASSERT_SUCCEEDED(hr); ComPtr uiElement; hr = canvas.As(&uiElement); @@ -560,14 +560,10 @@ QWinRTScreen::QWinRTScreen() d->cursor.reset(new QWinRTCursor); -#ifdef Q_OS_WINPHONE - ComPtr statusBarStatics; - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_StatusBar).Get(), - IID_PPV_ARGS(&statusBarStatics)); - Q_ASSERT_SUCCEEDED(hr); - hr = statusBarStatics->GetForCurrentView(&d->statusBar); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + hr = d->view.As(&d->view2); Q_ASSERT_SUCCEEDED(hr); -#endif // Q_OS_WINPHONE +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) } QWinRTScreen::~QWinRTScreen() @@ -587,12 +583,12 @@ QWinRTScreen::~QWinRTScreen() hr = (d->displayInformation.Get()->*i.key())(i.value()); Q_ASSERT_SUCCEEDED(hr); } -#ifdef Q_OS_WINPHONE - for (QHash::const_iterator i = d->statusBarTokens.begin(); i != d->statusBarTokens.end(); ++i) { - hr = (d->statusBar.Get()->*i.key())(i.value()); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + for (QHash::const_iterator i = d->view2Tokens.begin(); i != d->view2Tokens.end(); ++i) { + hr = (d->view2.Get()->*i.key())(i.value()); Q_ASSERT_SUCCEEDED(hr); } -#endif //Q_OS_WINPHONE +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) return hr; }); RETURN_VOID_IF_FAILED("Failed to unregister screen event callbacks"); @@ -601,33 +597,17 @@ QWinRTScreen::~QWinRTScreen() QRect QWinRTScreen::geometry() const { Q_D(const QWinRTScreen); - return QRect(QPoint(), (d->logicalSize * d->scaleFactor).toSize()); + return QRect(QPoint(), QSizeF(d->logicalRect.size() * d->scaleFactor).toSize()); } -#ifdef Q_OS_WINPHONE QRect QWinRTScreen::availableGeometry() const { Q_D(const QWinRTScreen); - QRect statusBar; - QEventDispatcherWinRT::runOnXamlThread([d, &statusBar]() { - HRESULT hr; - Rect rect; - hr = d->statusBar->get_OccludedRect(&rect); - Q_ASSERT_SUCCEEDED(hr); - statusBar.setRect(qRound(rect.X * d->scaleFactor), - qRound(rect.Y * d->scaleFactor), - qRound(rect.Width * d->scaleFactor), - qRound(rect.Height * d->scaleFactor)); - return S_OK; - }); - - return geometry().adjusted( - d->orientation == Qt::LandscapeOrientation ? statusBar.width() : 0, - d->orientation == Qt::PortraitOrientation ? statusBar.height() : 0, - d->orientation == Qt::InvertedLandscapeOrientation ? -statusBar.width() : 0, - 0); + return QRectF((d->visibleRect.x() - d->logicalRect.x())* d->scaleFactor, + (d->visibleRect.y() - d->logicalRect.y()) * d->scaleFactor, + d->visibleRect.width() * d->scaleFactor, + d->visibleRect.height() * d->scaleFactor).toRect(); } -#endif //Q_OS_WINPHONE int QWinRTScreen::depth() const { @@ -642,8 +622,8 @@ QImage::Format QWinRTScreen::format() const QSizeF QWinRTScreen::physicalSize() const { Q_D(const QWinRTScreen); - return QSizeF(d->logicalSize.width() * d->scaleFactor / d->physicalDpi.first * qreal(25.4), - d->logicalSize.height() * d->scaleFactor / d->physicalDpi.second * qreal(25.4)); + return QSizeF(d->logicalRect.width() * d->scaleFactor / d->physicalDpi.first * qreal(25.4), + d->logicalRect.height() * d->scaleFactor / d->physicalDpi.second * qreal(25.4)); } QDpi QWinRTScreen::logicalDpi() const @@ -720,29 +700,6 @@ Xaml::IDependencyObject *QWinRTScreen::canvas() const return d->canvas.Get(); } -#ifdef Q_OS_WINPHONE -void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window) -{ - Q_D(QWinRTScreen); - qCDebug(lcQpaWindows) << __FUNCTION__ << window << visible; - - const Qt::WindowFlags windowType = window->flags() & Qt::WindowType_Mask; - if (!window || (windowType != Qt::Window && windowType != Qt::Dialog)) - return; - - QEventDispatcherWinRT::runOnXamlThread([d, visible]() { - HRESULT hr; - ComPtr op; - if (visible) - hr = d->statusBar->ShowAsync(&op); - else - hr = d->statusBar->HideAsync(&op); - Q_ASSERT_SUCCEEDED(hr); - return S_OK; - }); -} -#endif //Q_OS_WINPHONE - void QWinRTScreen::initialize() { Q_D(QWinRTScreen); @@ -765,15 +722,14 @@ void QWinRTScreen::initialize() Q_ASSERT_SUCCEEDED(hr); hr = d->coreWindow->add_PointerWheelChanged(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); Q_ASSERT_SUCCEEDED(hr); -#ifndef Q_OS_WINPHONE - hr = d->coreWindow->add_SizeChanged(Callback(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + hr = d->view2->add_VisibleBoundsChanged(Callback(this, &QWinRTScreen::onWindowSizeChanged).Get(), &d->view2Tokens[&IApplicationView2::remove_VisibleBoundsChanged]); Q_ASSERT_SUCCEEDED(hr); #else - hr = d->statusBar->add_Showing(Callback(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->statusBar->add_Hiding(Callback(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]); - Q_ASSERT_SUCCEEDED(hr); -#endif + hr = d->coreWindow->add_SizeChanged(Callback(this, &QWinRTScreen::onWindowSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); + Q_ASSERT_SUCCEEDED(hr) +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + hr = d->coreWindow->add_Activated(Callback(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); Q_ASSERT_SUCCEEDED(hr); hr = d->coreWindow->add_Closed(Callback(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); @@ -801,11 +757,6 @@ void QWinRTScreen::addWindow(QWindow *window) if (window == topWindow()) return; -#ifdef Q_OS_WINPHONE - if (window->visibility() != QWindow::Maximized && window->visibility() != QWindow::Windowed) - setStatusBarVisibility(false, window); -#endif - d->visibleWindows.prepend(window); QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); @@ -817,11 +768,6 @@ void QWinRTScreen::removeWindow(QWindow *window) Q_D(QWinRTScreen); qCDebug(lcQpaWindows) << __FUNCTION__ << window; -#ifdef Q_OS_WINPHONE - if (window->visibility() == QWindow::Minimized) - setStatusBarVisibility(false, window); -#endif - const bool wasTopWindow = window == topWindow(); if (!d->visibleWindows.removeAll(window)) return; @@ -1125,7 +1071,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) } it.value().area = QRectF(area.X * d->scaleFactor, area.Y * d->scaleFactor, area.Width * d->scaleFactor, area.Height * d->scaleFactor); - it.value().normalPosition = QPointF(point.X/d->logicalSize.width(), point.Y/d->logicalSize.height()); + it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height()); it.value().pressure = pressure; QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods); @@ -1174,22 +1120,6 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) return S_OK; } -HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *) -{ - Q_D(QWinRTScreen); - - Rect size; - HRESULT hr; - hr = d->coreWindow->get_Bounds(&size); - RETURN_OK_IF_FAILED("Failed to get window bounds"); - d->logicalSize = QSizeF(size.Width, size.Height); - qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalSize; - QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); - QPlatformScreen::resizeMaximizedWindows(); - handleExpose(); - return S_OK; -} - HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args) { Q_D(QWinRTScreen); @@ -1228,8 +1158,10 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent RETURN_OK_IF_FAILED("Failed to get visibility."); qCDebug(lcQpaWindows) << __FUNCTION__ << visible; QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); - if (visible) + if (visible) { handleExpose(); + onWindowSizeChanged(nullptr, nullptr); + } return S_OK; } @@ -1245,9 +1177,7 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable * if (d->orientation != newOrientation) { d->orientation = newOrientation; qCDebug(lcQpaWindows) << " New orientation:" << newOrientation; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - onSizeChanged(nullptr, nullptr); -#endif + onWindowSizeChanged(nullptr, nullptr); QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation); handleExpose(); // Clean broken frames caused by race between Qt and ANGLE } @@ -1291,20 +1221,35 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) return S_OK; } -#ifdef Q_OS_WINPHONE -HRESULT QWinRTScreen::onStatusBarShowing(IStatusBar *, IInspectable *) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *) +#else +HRESULT QWinRTScreen::onWindowSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *) +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) { - qCDebug(lcQpaWindows) << __FUNCTION__; - onSizeChanged(nullptr, nullptr); - return S_OK; -} + Q_D(QWinRTScreen); -HRESULT QWinRTScreen::onStatusBarHiding(IStatusBar *, IInspectable *) -{ - qCDebug(lcQpaWindows) << __FUNCTION__; - onSizeChanged(nullptr, nullptr); + HRESULT hr; + Rect windowSize; + + hr = d->coreWindow->get_Bounds(&windowSize); + RETURN_OK_IF_FAILED("Failed to get window bounds"); + d->logicalRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height); + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + Rect visibleRect; + hr = d->view2->get_VisibleBounds(&visibleRect); + RETURN_OK_IF_FAILED("Failed to get window visible bounds"); + d->visibleRect = QRectF(visibleRect.X, visibleRect.Y, visibleRect.Width, visibleRect.Height); +#else + d->visibleRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height); +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + + qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalRect; + QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); + QPlatformScreen::resizeMaximizedWindows(); + handleExpose(); return S_OK; } -#endif //Q_OS_WINPHONE QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index ac9db9bfef..a5c1d24d51 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -62,7 +62,7 @@ namespace ABI { struct IWindow; } namespace ViewManagement { - struct IStatusBar; + struct IApplicationView; } } namespace Graphics { @@ -85,10 +85,9 @@ class QWinRTScreen : public QPlatformScreen public: explicit QWinRTScreen(); ~QWinRTScreen(); + QRect geometry() const Q_DECL_OVERRIDE; -#ifdef Q_OS_WINPHONE QRect availableGeometry() const Q_DECL_OVERRIDE; -#endif int depth() const Q_DECL_OVERRIDE; QImage::Format format() const Q_DECL_OVERRIDE; QSizeF physicalSize() const Q_DECL_OVERRIDE; @@ -112,10 +111,6 @@ public: ABI::Windows::UI::Core::ICoreWindow *coreWindow() const; ABI::Windows::UI::Xaml::IDependencyObject *canvas() const; -#ifdef Q_OS_WINPHONE - void setStatusBarVisibility(bool visible, QWindow *window); -#endif - void initialize(); private: @@ -127,7 +122,6 @@ private: HRESULT onPointerEntered(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *); HRESULT onPointerExited(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *); HRESULT onPointerUpdated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *); - HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *); @@ -136,10 +130,10 @@ private: HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); - -#ifdef Q_OS_WINPHONE - HRESULT onStatusBarShowing(ABI::Windows::UI::ViewManagement::IStatusBar *, IInspectable *); - HRESULT onStatusBarHiding(ABI::Windows::UI::ViewManagement::IStatusBar *, IInspectable *); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + HRESULT onWindowSizeChanged(ABI::Windows::UI::ViewManagement::IApplicationView *, IInspectable *); +#else + HRESULT onWindowSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); #endif QScopedPointer d_ptr; diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 07904ffbf7..f5407f8779 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -319,10 +319,6 @@ void QWinRTWindow::setWindowState(Qt::WindowState state) if (d->state == state) return; -#ifdef Q_OS_WINPHONE - d->screen->setStatusBarVisibility(state == Qt::WindowMaximized || state == Qt::WindowNoState, window()); -#endif - if (state == Qt::WindowMinimized) setUIElementVisibility(d->uiElement.Get(), false); -- cgit v1.2.3 From 8d169943eb4421b6bf3165ff42d9444f282fb03c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 12 Apr 2016 13:39:18 +0200 Subject: QWindowsLocalCodec::convertFromUnicode(): preclude stack overflow. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This method is called by QString::toLocal8Bit_helper(), so using QString::toLocal8Bit() on the input in an error message on failure to decode would be apt to recurse on the same data (if such an error ever arises). Furthermore, the qWarning()'s format string even claimed what it was displaying was in UTF-8. Fix by using native fprintf and UTF-16. Thanks to Frédéric Marchal for spotting this and checking that such errors aren't (at present) possible. Change-Id: I1ad441f2e3700bc01256d6c1718d404e27bce488 Reviewed-by: Thiago Macieira --- src/corelib/codecs/qwindowscodec.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/corelib/codecs/qwindowscodec.cpp b/src/corelib/codecs/qwindowscodec.cpp index dded93ccb5..a7c6f72422 100644 --- a/src/corelib/codecs/qwindowscodec.cpp +++ b/src/corelib/codecs/qwindowscodec.cpp @@ -208,10 +208,12 @@ QByteArray QWindowsLocalCodec::convertFromUnicode(const QChar *ch, int uclen, Co 0, 0, 0, &used_def)); // and try again... } else { + // Fail. Probably can't happen in fact (dwFlags is 0). #ifndef QT_NO_DEBUG - // Fail. - qWarning("WideCharToMultiByte: Cannot convert multibyte text (error %d): %s (UTF-8)", - r, QString(ch, uclen).toLocal8Bit().data()); + // Can't use qWarning(), as it'll recurse to handle %ls + fprintf(stderr, + "WideCharToMultiByte: Cannot convert multibyte text (error %d): %ls\n", + r, reinterpret_cast(QString(ch, uclen).utf16())); #endif break; } -- cgit v1.2.3 From daebbcf5f4438fec636e7663f272954ce2145ff0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 29 Jan 2016 11:07:56 +0100 Subject: Manual test qcursorhighdpi: Add drag and drop. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add dragging functionality to the labels showing a pixmap cursor, allowing for testing DnD with pixmaps with device pixel ratio. Task-number: QTBUG-46068 Task-number: QTBUG-50938 Change-Id: If6781f380864e614efd4328e8b880b57cd900511 Reviewed-by: Morten Johan Sørvig --- tests/manual/qcursor/qcursorhighdpi/main.cpp | 69 ++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/tests/manual/qcursor/qcursorhighdpi/main.cpp b/tests/manual/qcursor/qcursorhighdpi/main.cpp index fc45ae00d1..745c1c4421 100644 --- a/tests/manual/qcursor/qcursorhighdpi/main.cpp +++ b/tests/manual/qcursor/qcursorhighdpi/main.cpp @@ -44,10 +44,12 @@ #include #include +#include #include #include #include +#include #include #include @@ -68,6 +70,14 @@ #include #include +#if QT_VERSION < 0x050000 +QDebug operator<<(QDebug d, const QPixmap &p) +{ + d.nospace() << "QPixmap(" << p.size() << ')'; + return d; +} +#endif // Qt 4 + // High DPI cursor test for testing cursor sizes in multi-screen setups. // It creates one widget per screen with a grid of standard cursors, // pixmap / bitmap cursors and pixmap / bitmap cursors with device pixel ratio 2. @@ -159,6 +169,49 @@ static QCursor bitmapCursorDevicePixelRatio(int size, int dpr) } #endif // Qt 5 +// A label from which a pixmap can be dragged for testing drag with pixmaps/DPR. +class DraggableLabel : public QLabel { +public: + explicit DraggableLabel(const QPixmap &p, const QString &text, QWidget *parent = Q_NULLPTR) + : QLabel(text, parent), m_pixmap(p) + { + setToolTip(QLatin1String("Click to drag away the pixmap. Press Shift to set a circular mask.")); + } + +protected: + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +private: + const QPixmap m_pixmap; +}; + +void DraggableLabel::mousePressEvent(QMouseEvent *) +{ + QMimeData *mimeData = new QMimeData; + mimeData->setImageData(qVariantFromValue(m_pixmap)); + QDrag *drag = new QDrag(this); + QPixmap pixmap = m_pixmap; + if (QApplication::keyboardModifiers() & Qt::ShiftModifier) { + QBitmap mask(pixmap.width(), pixmap.height()); + mask.clear(); + QPainter painter(&mask); + painter.setBrush(Qt::color1); + const int hx = pixmap.width() / 2; + const int hy = pixmap.width() / 2; + painter.drawEllipse(QPoint(hx, hy), hx, hy); + pixmap.setMask(mask); + } + drag->setMimeData(mimeData); + drag->setPixmap(pixmap); + QPoint sizeP = QPoint(m_pixmap.width(), m_pixmap.height()); +#if QT_VERSION > 0x050000 + sizeP /= int(m_pixmap.devicePixelRatio()); +#endif // Qt 5 + drag->setHotSpot(sizeP / 2); + qDebug() << "Dragging:" << m_pixmap; + drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); +} + // Vertical ruler widget with 10 px marks class VerticalRuler : public QWidget { public: @@ -210,8 +263,15 @@ static QLabel *createCursorLabel(const QCursor &cursor, const QString &additiona #endif // Qt 5 if (!additionalText.isEmpty()) labelText += ' ' + additionalText; - QLabel *result = new QLabel(labelText); - result->setFrameShape(QFrame::Box); + const QPixmap cursorPixmap = cursor.pixmap(); + QLabel *result = Q_NULLPTR; + if (cursorPixmap.size().isEmpty()) { + result = new QLabel(labelText); + result->setFrameShape(QFrame::Box); + } else { + result = new DraggableLabel(cursor.pixmap(), labelText); + result->setFrameShape(QFrame::StyledPanel); + } result->setCursor(cursor); return result; } @@ -304,7 +364,10 @@ int main(int argc, char *argv[]) QDesktopWidget *desktopWidget = app.desktop(); - for (int s = desktopWidget->screenCount() - 1; s >= 0; --s) { + const int lastScreen = arguments.contains("-p") + ? 0 // Primary screen only + : desktopWidget->screenCount() - 1; // All screens + for (int s = lastScreen; s >= 0; --s) { MainWindowPtr window(new MainWindow(desktopWidget->screen(s))); const QPoint pos = desktopWidget->screenGeometry(s).center() - QPoint(200, 100); window->move(pos); -- cgit v1.2.3 From 32a419229ae3a6165e3c793ff132bb9803594fb0 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 28 Mar 2016 15:28:43 +0300 Subject: Fix wrong style of QMessageBox on Android. Extracting the theme information seems pretty buggy on some Android devices, so let the platform functions do it instead. Task-number: QTBUG-35687 Change-Id: Ib27e846fad98624c3c396dab06d476281de693f7 Reviewed-by: Christian Stromme --- .../qt5/android/QtMessageDialogHelper.java | 32 +++------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java b/src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java index 341bc159c8..f9ece74de3 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java @@ -1,6 +1,6 @@ /**************************************************************************** ** - ** Copyright (C) 2013 BogDan Vatra + ** Copyright (C) 2016 BogDan Vatra ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Android port of the Qt Toolkit. @@ -172,30 +172,6 @@ public class QtMessageDialogHelper m_buttonsList.add(new ButtonStruct(this, id, text)); } - private void setTextAppearance(TextView view, String attr, String style) - { - try { - int[] attrs = (int[]) Class.forName("android.R$styleable").getDeclaredField("TextAppearance").get(null); - final TypedArray a = m_theme.obtainStyledAttributes(null, - attrs, - Class.forName("android.R$attr").getDeclaredField(attr).getInt(null), - Class.forName("android.R$style").getDeclaredField(style).getInt(null)); - final int textSize = a.getDimensionPixelSize( - Class.forName("android.R$styleable").getDeclaredField("TextAppearance_textSize").getInt(null), 0); - if (textSize != 0) - view.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); - - final int textColor = a.getColor( - Class.forName("android.R$styleable").getDeclaredField("TextAppearance_textColor").getInt(null), 0x3138); - if (textColor != 0x3138) - view.setTextColor(textColor); - - a.recycle(); - } catch (Exception e) { - e.printStackTrace(); - } - } - private Drawable getStyledDrawable(String drawable) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { int[] attrs = {Class.forName("android.R$attr").getDeclaredField(drawable).getInt(null)}; @@ -252,7 +228,7 @@ public class QtMessageDialogHelper view.setLongClickable(true); view.setText(m_text); - setTextAppearance(view, "textAppearanceMedium", "TextAppearance_Medium"); + view.setTextAppearance(m_activity, android.R.style.TextAppearance_Medium); RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layout.setMargins(16, 8, 16, 8); @@ -269,7 +245,7 @@ public class QtMessageDialogHelper view.setLongClickable(true); view.setText(m_informativeText); - setTextAppearance(view, "textAppearanceMedium", "TextAppearance_Medium"); + view.setTextAppearance(m_activity, android.R.style.TextAppearance_Medium); RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layout.setMargins(16, 8, 16, 8); @@ -289,7 +265,7 @@ public class QtMessageDialogHelper view.setLongClickable(true); view.setText(m_detailedText); - setTextAppearance(view, "textAppearanceSmall", "TextAppearance_Small"); + view.setTextAppearance(m_activity, android.R.style.TextAppearance_Small); RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layout.setMargins(16, 8, 16, 8); -- cgit v1.2.3 From d229ed77dbb3b97690d3839e901ca51670eaae75 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 14 Apr 2016 18:18:47 +0300 Subject: Android: Update Ministro's url Change-Id: Ib255c8127477f3ad4f3bb0c09569d142f51a6be4 Reviewed-by: Christian Stromme --- src/android/templates/res/values/libs.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml index 4d68673cb0..ee3f5e940e 100644 --- a/src/android/templates/res/values/libs.xml +++ b/src/android/templates/res/values/libs.xml @@ -1,7 +1,7 @@ - https://download.qt-project.org/ministro/android/qt5/qt-5.4 + https://download.qt.io/ministro/android/qt5/qt-5.6