Merge remote-tracking branch 'origin/5.14' into 5.15

Change-Id: Ic062a5bd62621877b17cc0d47303b3c879241385
This commit is contained in:
Qt Forward Merge Bot 2019-10-22 01:00:49 +02:00
commit 563dc21c51
15 changed files with 115 additions and 67 deletions

View File

@ -11,6 +11,12 @@ dita.metadata.default.audience = programmer
navigation.homepage = index.html
navigation.hometitle = "Qt $QT_VER"
#Words to ignore for auto-linking
ignorewords += \
macOS \
WebChannel \
OpenGL
sourcedirs += includes $$BUILDDIR
url = http://doc.qt.io/qt-5

View File

@ -1865,7 +1865,20 @@ bool QGuiApplication::event(QEvent *e)
{
if(e->type() == QEvent::LanguageChange) {
setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
} else if (e->type() == QEvent::Quit) {
// Close open windows. This is done in order to deliver de-expose
// events while the event loop is still running.
for (QWindow *topLevelWindow : QGuiApplication::topLevelWindows()) {
// Already closed windows will not have a platform window, skip those
if (!topLevelWindow->handle())
continue;
if (!topLevelWindow->close()) {
e->ignore();
return true;
}
}
}
return QCoreApplication::event(e);
}
@ -1942,6 +1955,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e);
QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); }
break;
case QWindowSystemInterfacePrivate::ApplicationTermination:
QGuiApplicationPrivate::processApplicationTermination(e);
break;
case QWindowSystemInterfacePrivate::FlushEvents: {
QWindowSystemInterfacePrivate::FlushEventsEvent *flushEventsEvent = static_cast<QWindowSystemInterfacePrivate::FlushEventsEvent *>(e);
QWindowSystemInterface::deferredFlushWindowSystemEvents(flushEventsEvent->flags); }
@ -3491,6 +3507,13 @@ bool QGuiApplicationPrivate::tryCloseRemainingWindows(QWindowList processedWindo
return true;
}
void QGuiApplicationPrivate::processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *windowSystemEvent)
{
QEvent event(QEvent::Quit);
QGuiApplication::sendSpontaneousEvent(QGuiApplication::instance(), &event);
windowSystemEvent->eventAccepted = event.isAccepted();
}
/*!
\since 5.2
\fn Qt::ApplicationState QGuiApplication::applicationState()

View File

@ -141,6 +141,8 @@ public:
static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
static void processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
static void updateFilteredScreenOrientation(QScreen *screen);
static void reportScreenOrientationChange(QScreen *screen);
static void processScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e);

View File

@ -285,6 +285,12 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::Application
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleApplicationTermination)
{
auto *e = new QWindowSystemInterfacePrivate::WindowSystemEvent(QWindowSystemInterfacePrivate::ApplicationTermination);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *window, const QRect &newGeometry)
: WindowSystemEvent(GeometryChange)
, window(window)

View File

@ -215,6 +215,9 @@ public:
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static bool handleApplicationTermination();
#if QT_CONFIG(draganddrop)
#if QT_DEPRECATED_SINCE(5, 11)
QT_DEPRECATED static QPlatformDragQtResponse handleDrag(QWindow *window, const QMimeData *dropData,

View File

@ -99,7 +99,8 @@ public:
ApplicationStateChanged = 0x19,
FlushEvents = 0x20,
WindowScreenChanged = 0x21,
SafeAreaMarginsChanged = 0x22
SafeAreaMarginsChanged = 0x22,
ApplicationTermination = 0x23
};
class WindowSystemEvent {

View File

@ -3518,14 +3518,36 @@ QRhiResource::Type QRhiSwapChain::resourceType() const
\c{currentPixelSize() != surfacePixelSize()} then the swapchain needs to be
resized.
\note Typical rendering logic will call this function to get the output
size when starting to prepare a new frame, and base dependent calculations
(such as, the viewport) on the size returned from this function.
While in many cases the value is the same as \c{QWindow::size() *
QWindow::devicePixelRatio()}, relying on the QWindow-reported size is not
guaranteed to be correct on all platforms and graphics API implementations.
Using this function is therefore strongly recommended whenever there is a
need to identify the dimensions, in pixels, of the output layer or surface.
This also has the added benefit of avoiding potential data races when QRhi
is used on a dedicated rendering thread, because the need to call QWindow
functions, that may then access data updated on the main thread, is
avoided.
\sa surfacePixelSize()
*/
/*!
\fn QSize QRhiSwapChain::surfacePixelSize()
\return The size of the window's associated surface or layer. Do not assume
this is the same as QWindow::size() * QWindow::devicePixelRatio().
\return The size of the window's associated surface or layer.
\warning Do not assume this is the same as \c{QWindow::size() *
QWindow::devicePixelRatio()}. With some graphics APIs and windowing system
interfaces (for example, Vulkan) there is a theoretical possibility for a
surface to assume a size different from the associated window. To support
these cases, rendering logic must always base size-derived calculations
(such as, viewports) on the size reported from QRhiSwapChain, and never on
the size queried from QWindow.
\note Can also be called before buildOrResize(), if at least window() is
already set) This in combination with currentPixelSize() allows to detect

View File

@ -2125,22 +2125,7 @@ void QTextEngine::itemize() const
}
#if QT_CONFIG(harfbuzz)
analysis = scriptAnalysis.data();
if (qt_useHarfbuzzNG()) {
// ### pretend HB-old behavior for now
for (int i = 0; i < length; ++i) {
switch (analysis[i].script) {
case QChar::Script_Latin:
case QChar::Script_Hiragana:
case QChar::Script_Katakana:
case QChar::Script_Bopomofo:
case QChar::Script_Han:
analysis[i].script = QChar::Script_Common;
break;
default:
break;
}
}
} else {
if (!qt_useHarfbuzzNG()) {
for (int i = 0; i < length; ++i)
analysis[i].script = hbscript_to_script(script_to_hbscript(analysis[i].script));
}
@ -3619,7 +3604,12 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end,
int clusterLength = 0;
if (si->analysis.script != QChar::Script_Common &&
si->analysis.script != QChar::Script_Greek) {
si->analysis.script != QChar::Script_Greek &&
si->analysis.script != QChar::Script_Latin &&
si->analysis.script != QChar::Script_Hiragana &&
si->analysis.script != QChar::Script_Katakana &&
si->analysis.script != QChar::Script_Bopomofo &&
si->analysis.script != QChar::Script_Han) {
if (glyph_pos == -1)
return si->position + end;
else {

View File

@ -88,10 +88,13 @@
#include <qpa/qwindowsysteminterface.h>
#include <qwindowdefs.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
QT_END_NAMESPACE
QT_USE_NAMESPACE
@implementation QCocoaApplicationDelegate {
bool startedQuit;
NSObject <NSApplicationDelegate> *reflectionDelegate;
bool inLaunch;
}
@ -140,46 +143,30 @@ QT_USE_NAMESPACE
return [[self.dockMenu retain] autorelease];
}
- (BOOL)canQuit
{
QCloseEvent ev;
QGuiApplication::sendEvent(qGuiApp, &ev);
return ev.isAccepted();
}
// This function will only be called when NSApp is actually running.
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
if ([reflectionDelegate respondsToSelector:_cmd])
return [reflectionDelegate applicationShouldTerminate:sender];
if ([self canQuit]) {
if (!startedQuit) {
startedQuit = true;
// Close open windows. This is done in order to deliver de-expose
// events while the event loop is still running.
const QWindowList topLevels = QGuiApplication::topLevelWindows();
for (int i = 0; i < topLevels.size(); ++i) {
QWindow *topLevelWindow = topLevels.at(i);
// Already closed windows will not have a platform window, skip those
if (topLevelWindow->handle())
QWindowSystemInterface::handleCloseEvent(topLevelWindow);
}
QWindowSystemInterface::flushWindowSystemEvents();
QGuiApplication::exit(0);
startedQuit = false;
}
}
if (QGuiApplicationPrivate::instance()->threadData->eventLoops.isEmpty()) {
// INVARIANT: No event loop is executing. This probably
// means that Qt is used as a plugin, or as a part of a native
// Cocoa application. In any case it should be fine to
// terminate now:
// No event loop is executing. This probably means that Qt is used as a plugin,
// or as a part of a native Cocoa application. In any case it should be fine to
// terminate now.
qCDebug(lcQpaApplication) << "No running event loops, terminating now";
return NSTerminateNow;
}
if (!QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>()) {
qCDebug(lcQpaApplication) << "Application termination canceled";
return NSTerminateCancel;
}
// Even if the application termination was accepted by the application we can't
// return NSTerminateNow, as that would trigger AppKit to ultimately call exit().
// We need to ensure that the runloop continues spinning so that we can return
// from our own event loop back to main(), and exit from there.
qCDebug(lcQpaApplication) << "Termination accepted, but returning to runloop for exit through main()";
return NSTerminateCancel;
}

View File

@ -42,6 +42,8 @@
#include <QCoreApplication>
#include <QFileOpenEvent>
#include <qpa/qwindowsysteminterface.h>
#include <Entry.h>
#include <Path.h>
@ -52,8 +54,7 @@ QHaikuApplication::QHaikuApplication(const char *signature)
bool QHaikuApplication::QuitRequested()
{
QEvent quitEvent(QEvent::Quit);
QCoreApplication::sendEvent(QCoreApplication::instance(), &quitEvent);
QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>();
return true;
}

View File

@ -42,6 +42,8 @@
#ifndef QT_NO_SESSIONMANAGER
#include <qpa/qwindowsysteminterface.h>
#include <qguiapplication.h>
#include <qdatetime.h>
#include <qfileinfo.h>
@ -289,8 +291,7 @@ static void sm_dieCallback(SmcConn smcConn, SmPointer /* clientData */)
if (smcConn != smcConnection)
return;
resetSmState();
QEvent quitEvent(QEvent::Quit);
QGuiApplication::sendEvent(qApp, &quitEvent);
QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>();
}
static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData)

View File

@ -1680,7 +1680,7 @@ static void writeResourceIcon(QTextStream &output,
"Selected", "Off");
}
if (i->hasElementSelectedOn()) {
writeIconAddFile(output, indent, iconName, i->elementSelectedOff()->text(),
writeIconAddFile(output, indent, iconName, i->elementSelectedOn()->text(),
"Selected", "On");
}
}

View File

@ -549,6 +549,10 @@
If the property references an enum declared with Q_ENUMS, you should
reference its constants by name, i.e., not their numeric value.
\note Use the qproperty syntax with care, as it modifies the
widget that is being painted. Also, the qproperty syntax is evaluated only
once, which is when the widget is polished by the style. This means that any
attempt to use them in pseudo-states such as QPushButton:hover, will not work.
*/
/*!

View File

@ -1866,22 +1866,19 @@ void QApplication::aboutQt()
bool QApplication::event(QEvent *e)
{
Q_D(QApplication);
if(e->type() == QEvent::Close) {
QCloseEvent *ce = static_cast<QCloseEvent*>(e);
ce->accept();
if (e->type() == QEvent::Quit) {
closeAllWindows();
const QWidgetList list = topLevelWidgets();
for (auto *w : list) {
for (auto *w : topLevelWidgets()) {
if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) &&
(!(w->windowType() == Qt::Dialog) || !w->parentWidget())) {
ce->ignore();
break;
e->ignore();
return true;
}
}
if (ce->isAccepted()) {
return true;
}
// Explicitly call QCoreApplication instead of QGuiApplication so that
// we don't let QGuiApplication close any windows we skipped earlier in
// closeAllWindows(). FIXME: Unify all this close magic through closeAllWindows.
return QCoreApplication::event(e);
#ifndef Q_OS_WIN
} else if (e->type() == QEvent::LocaleChange) {
// on Windows the event propagation is taken care by the

View File

@ -2068,7 +2068,12 @@ void tst_QTextLayout::cursorInLigatureWithMultipleLines()
void tst_QTextLayout::xToCursorForLigatures()
{
#if defined(Q_OS_WIN32)
QTextLayout layout("fi", QFont("Calibri", 20));
#else
QTextLayout layout("fi", QFont("Times", 20));
#endif
layout.setCacheEnabled(true);
layout.beginLayout();
QTextLine line = layout.createLine();