summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-22 01:00:49 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-22 01:00:49 +0200
commit563dc21c517647e72785247bbbf07d1b6553f59c (patch)
tree6c96f317da30520d1ad253a3785878abc4ec1cf1
parent35adb74ddd915831789f0175423660f8e898942e (diff)
parentaa4b0f5cb7e84046530fbc26581f777506fea658 (diff)
Merge remote-tracking branch 'origin/5.14' into 5.15
-rw-r--r--doc/global/config.qdocconf6
-rw-r--r--src/gui/kernel/qguiapplication.cpp23
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp6
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h3
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h3
-rw-r--r--src/gui/rhi/qrhi.cpp26
-rw-r--r--src/gui/text/qtextengine.cpp24
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm49
-rw-r--r--src/plugins/platforms/haiku/qhaikuapplication.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp5
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp2
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc4
-rw-r--r--src/widgets/kernel/qapplication.cpp19
-rw-r--r--tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp5
15 files changed, 115 insertions, 67 deletions
diff --git a/doc/global/config.qdocconf b/doc/global/config.qdocconf
index 0b276c400f..16d4e5c63a 100644
--- a/doc/global/config.qdocconf
+++ b/doc/global/config.qdocconf
@@ -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
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index b4c4231910..f09f7e941b 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -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()
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index e28607bad6..26f65b2f16 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -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);
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 5f61853a6d..4f1056e906 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -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)
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 4a0bc858a9..d5a4ad30d8 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -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,
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 55fd181ef0..6e4bce607e 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -99,7 +99,8 @@ public:
ApplicationStateChanged = 0x19,
FlushEvents = 0x20,
WindowScreenChanged = 0x21,
- SafeAreaMarginsChanged = 0x22
+ SafeAreaMarginsChanged = 0x22,
+ ApplicationTermination = 0x23
};
class WindowSystemEvent {
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index dabad35688..8ef98d2e42 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -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
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index b37353bf2c..209433dac5 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -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 {
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 33a45985a8..9b0a6b1b86 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -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;
}
diff --git a/src/plugins/platforms/haiku/qhaikuapplication.cpp b/src/plugins/platforms/haiku/qhaikuapplication.cpp
index b75810c453..de4acdfd4a 100644
--- a/src/plugins/platforms/haiku/qhaikuapplication.cpp
+++ b/src/plugins/platforms/haiku/qhaikuapplication.cpp
@@ -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;
}
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index 2303ccf806..f880d4d722 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -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)
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
index fd5f8c9017..717bff4a51 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.cpp
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -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");
}
}
diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
index 00323eace6..84233e4b62 100644
--- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
@@ -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.
*/
/*!
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 3223781b63..dfa1bc23b1 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -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
diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
index a474acd790..2dcca0209e 100644
--- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
@@ -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();