diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-03-15 01:00:11 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-03-15 01:00:11 +0100 |
commit | 8264e495fa9220c101a8a913701a0b8834a6d58b (patch) | |
tree | 069aa1d3efab926991c1edfc5b69a3d9e58dcfba | |
parent | 80f52812f2651e6d427bb3dd2e338b60fb25d48b (diff) | |
parent | 8eb3944dac81b8c51d7bac7784204d457551b50c (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Change-Id: I8b5a10d897a926078895ae41f48cdbd2474902b8
48 files changed, 484 insertions, 281 deletions
diff --git a/doc/src/images/dirview-example.png b/doc/src/images/dirview-example.png Binary files differindex 6412ead5b2..deb06267f6 100644 --- a/doc/src/images/dirview-example.png +++ b/doc/src/images/dirview-example.png diff --git a/doc/src/images/dynamiclayouts-example.png b/doc/src/images/dynamiclayouts-example.png Binary files differnew file mode 100644 index 0000000000..b26d3725cc --- /dev/null +++ b/doc/src/images/dynamiclayouts-example.png diff --git a/examples/widgets/animation/sub-attaq/mainwindow.cpp b/examples/widgets/animation/sub-attaq/mainwindow.cpp index 106404682d..b08a7d9f98 100644 --- a/examples/widgets/animation/sub-attaq/mainwindow.cpp +++ b/examples/widgets/animation/sub-attaq/mainwindow.cpp @@ -84,8 +84,13 @@ MainWindow::MainWindow() : QMainWindow(0) view->setAlignment(Qt::AlignLeft | Qt::AlignTop); scene->setupScene(newAction, quitAction); #ifndef QT_NO_OPENGL - view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + QGLWidget *glWidget = new QGLWidget(QGLFormat(QGL::SampleBuffers)); + if (glWidget->context()->isValid()) { + view->setViewport(glWidget); + } else { + qWarning("Unable to create an Open GL context with sample buffers, not using Open GL."); + delete glWidget; + } #endif - setCentralWidget(view); } diff --git a/examples/widgets/doc/src/dirview.qdoc b/examples/widgets/doc/src/dirview.qdoc index 3d58553b8d..d9a16fa58d 100644 --- a/examples/widgets/doc/src/dirview.qdoc +++ b/examples/widgets/doc/src/dirview.qdoc @@ -31,8 +31,38 @@ \ingroup examples-itemviews \brief This example demonstrates the usage of a tree view. - \brief The Dir View example shows a tree view onto the local filing system. It uses the - QFileSystemModel class to provide file and directory information. + The Dir View example shows a tree view of the local file + system. It uses the QFileSystemModel class to provide file + and directory information. - \image dirview-example.png + \borderedimage dirview-example.png + + The example supports a number of command line options. + These options include: + \list + \li Application description + \li -help option + \li -version option + \li if the optionc {-c} is specified, the application will not + use custom directory options + \endlist + + \quotefromfile itemviews/dirview/main.cpp + \skipto QCommandLineParser parser + \printuntil parser.positionalArguments + + Declares a QFileSystemModel as data model for viewing + the local file system. QFileSystem works with a cache, that is, + it is updated continually with QFileSystemWatcher on that folder. + + \skipto QFileSystemModel + \printuntil tree.setModel + + Creates a model/view implementation called \c tree + for viewing the filesystem. + + \skipto tree.setAnimated(false) + \printuntil tree.setWindowTitle + + Sets some formatting options for \c tree. */ diff --git a/examples/widgets/doc/src/dynamiclayouts.qdoc b/examples/widgets/doc/src/dynamiclayouts.qdoc index be59aa6ab9..0b9d43c98e 100644 --- a/examples/widgets/doc/src/dynamiclayouts.qdoc +++ b/examples/widgets/doc/src/dynamiclayouts.qdoc @@ -34,7 +34,82 @@ applications. The widget placement depends on whether \c Horizontal or \c Vertical is chosen. + \borderedimage dynamiclayouts-example.png For more information, visit the \l{Layout Management} page. + \section1 Dialog Constructor + + To begin with, the application creates the UI components by calling the + following methods: + + \list + \li createRotatableGroupBox() + \li createOptionsGroupBox() + \li createButtonBox() + \endlist + + It then adds the UI components to a GridLayout (\c mainLayout). + + Finally, \c Dialog::rotateWidgets() is called. + + \quotefromfile layouts/dynamiclayouts/dialog.cpp + \skipuntil createRotatableGroupBox + \printuntil setWindowTitle + + \section1 Creating the Main Widgets + + The \c createRotatableGroupBox() method creates a rotatable group box, + then adds a series of widgets: + + \list + \li QSpinBox + \li QSlider + \li QDial + \li QProgressBar + \endlist + + It goes on to add signals and slots to each widget, and assigns + a QGridLayout called \a rotatableLayout. + + \skipto Dialog::createRotatableGroupBox + \printuntil /^\}/ + + \section1 Adding Options + + \c createOptionsGroupBox() creates the following widgets: + \list + \li \c optionsGroupBox + \li \c buttonsOrientationLabel + \li \c buttonsOrientationComboBox. The orientation of the ComboBox is either + \c horizontal (default value) or \c vertical. These two values + are added during the startup of the application. It is not possible + to leave the option empty. + \endlist + + \skipto Dialog::createOptionsGroupBox() + \printuntil /^\}/ + + \section1 Adding Buttons + + createButtonBox() constructs a QDialogButtonBox called \c buttonBox + to which are added a \c closeButton, a \c helpButton and a + \c rotateWidgetsButton. + It then assigns a signal and a slot to each button in \c buttonBox. + + \skipto Dialog::createButtonBox() + \printuntil /^\}/ + + + \section1 Rotating the Widgets + + Removes the current widgets and activates the next widget. + + \quotefromfile layouts/dynamiclayouts/dialog.cpp + \skipto Dialog::rotateWidgets() + \printuntil rotatableLayout->addWidget(rotatableWidgets[i] + \printuntil } + \printuntil } + \include examples-run.qdocinc */ + diff --git a/examples/widgets/doc/src/graphicsview-flowlayout.qdoc b/examples/widgets/doc/src/graphicsview-flowlayout.qdoc index e5080c672d..13819f5499 100644 --- a/examples/widgets/doc/src/graphicsview-flowlayout.qdoc +++ b/examples/widgets/doc/src/graphicsview-flowlayout.qdoc @@ -36,5 +36,17 @@ \image graphicsflowlayout-example.png - See the \l{Flow Layout Example} for a corresponding widget-based example. + This example uses a Graphics View to display the widget, which is a more + customizable approach than displaying the flow layout in the application + window (See \l {Flow Layout Example}). + + Graphics View Flow Layout snippet: + + \snippet graphicsview/flowlayout/main.cpp 1 + + Flow Layout Example snippet: + + \snippet layouts/flowlayout/main.cpp 1 + + */ diff --git a/examples/widgets/graphicsview/flowlayout/main.cpp b/examples/widgets/graphicsview/flowlayout/main.cpp index 850302e175..74c03b9bce 100644 --- a/examples/widgets/graphicsview/flowlayout/main.cpp +++ b/examples/widgets/graphicsview/flowlayout/main.cpp @@ -47,7 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - +//! [1] #include "window.h" #include <QApplication> @@ -68,3 +68,4 @@ int main(int argc, char *argv[]) return app.exec(); } +//! [1] diff --git a/examples/widgets/layouts/dynamiclayouts/dialog.cpp b/examples/widgets/layouts/dynamiclayouts/dialog.cpp index 080d69204b..f46053372a 100644 --- a/examples/widgets/layouts/dynamiclayouts/dialog.cpp +++ b/examples/widgets/layouts/dynamiclayouts/dialog.cpp @@ -55,12 +55,12 @@ Dialog::Dialog(QWidget *parent) : QDialog(parent) { - createRotableGroupBox(); + createRotatableGroupBox(); createOptionsGroupBox(); createButtonBox(); mainLayout = new QGridLayout; - mainLayout->addWidget(rotableGroupBox, 0, 0); + mainLayout->addWidget(rotatableGroupBox, 0, 0); mainLayout->addWidget(optionsGroupBox, 1, 0); mainLayout->addWidget(buttonBox, 2, 0); setLayout(mainLayout); @@ -102,17 +102,17 @@ void Dialog::buttonsOrientationChanged(int index) void Dialog::rotateWidgets() { - Q_ASSERT(rotableWidgets.count() % 2 == 0); + Q_ASSERT(rotatableWidgets.count() % 2 == 0); - foreach (QWidget *widget, rotableWidgets) - rotableLayout->removeWidget(widget); + foreach (QWidget *widget, rotatableWidgets) + rotatableLayout->removeWidget(widget); - rotableWidgets.enqueue(rotableWidgets.dequeue()); + rotatableWidgets.enqueue(rotatableWidgets.dequeue()); - const int n = rotableWidgets.count(); + const int n = rotatableWidgets.count(); for (int i = 0; i < n / 2; ++i) { - rotableLayout->addWidget(rotableWidgets[n - i - 1], 0, i); - rotableLayout->addWidget(rotableWidgets[i], 1, i); + rotatableLayout->addWidget(rotatableWidgets[n - i - 1], 0, i); + rotatableLayout->addWidget(rotatableWidgets[i], 1, i); } } @@ -123,23 +123,23 @@ void Dialog::help() "dynamically.")); } -void Dialog::createRotableGroupBox() +void Dialog::createRotatableGroupBox() { - rotableGroupBox = new QGroupBox(tr("Rotable Widgets")); + rotatableGroupBox = new QGroupBox(tr("Rotatable Widgets")); - rotableWidgets.enqueue(new QSpinBox); - rotableWidgets.enqueue(new QSlider); - rotableWidgets.enqueue(new QDial); - rotableWidgets.enqueue(new QProgressBar); + rotatableWidgets.enqueue(new QSpinBox); + rotatableWidgets.enqueue(new QSlider); + rotatableWidgets.enqueue(new QDial); + rotatableWidgets.enqueue(new QProgressBar); - int n = rotableWidgets.count(); + int n = rotatableWidgets.count(); for (int i = 0; i < n; ++i) { - connect(rotableWidgets[i], SIGNAL(valueChanged(int)), - rotableWidgets[(i + 1) % n], SLOT(setValue(int))); + connect(rotatableWidgets[i], SIGNAL(valueChanged(int)), + rotatableWidgets[(i + 1) % n], SLOT(setValue(int))); } - rotableLayout = new QGridLayout; - rotableGroupBox->setLayout(rotableLayout); + rotatableLayout = new QGridLayout; + rotatableGroupBox->setLayout(rotatableLayout); rotateWidgets(); } @@ -154,8 +154,10 @@ void Dialog::createOptionsGroupBox() buttonsOrientationComboBox->addItem(tr("Horizontal"), Qt::Horizontal); buttonsOrientationComboBox->addItem(tr("Vertical"), Qt::Vertical); - connect(buttonsOrientationComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(buttonsOrientationChanged(int))); + connect(buttonsOrientationComboBox, + QOverload<int>::of(&QComboBox::currentIndexChanged), + this, + &Dialog::buttonsOrientationChanged); optionsLayout = new QGridLayout; optionsLayout->addWidget(buttonsOrientationLabel, 0, 0); @@ -173,7 +175,9 @@ void Dialog::createButtonBox() rotateWidgetsButton = buttonBox->addButton(tr("Rotate &Widgets"), QDialogButtonBox::ActionRole); - connect(rotateWidgetsButton, SIGNAL(clicked()), this, SLOT(rotateWidgets())); - connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); - connect(helpButton, SIGNAL(clicked()), this, SLOT(help())); + connect(rotateWidgetsButton, &QPushButton::clicked, this, &Dialog::rotateWidgets); + connect(closeButton, &QPushButton::clicked, this, &Dialog::close); + connect(helpButton, &QPushButton::clicked, this, &Dialog::help); } + + diff --git a/examples/widgets/layouts/dynamiclayouts/dialog.h b/examples/widgets/layouts/dynamiclayouts/dialog.h index 0ff0c12b38..923a6fe01b 100644 --- a/examples/widgets/layouts/dynamiclayouts/dialog.h +++ b/examples/widgets/layouts/dynamiclayouts/dialog.h @@ -76,12 +76,12 @@ private slots: void help(); private: - void createRotableGroupBox(); + void createRotatableGroupBox(); void createOptionsGroupBox(); void createButtonBox(); - QGroupBox *rotableGroupBox; - QQueue<QWidget *> rotableWidgets; + QGroupBox *rotatableGroupBox; + QQueue<QWidget *> rotatableWidgets; QGroupBox *optionsGroupBox; QLabel *buttonsOrientationLabel; @@ -93,7 +93,7 @@ private: QPushButton *rotateWidgetsButton; QGridLayout *mainLayout; - QGridLayout *rotableLayout; + QGridLayout *rotatableLayout; QGridLayout *optionsLayout; }; diff --git a/examples/widgets/layouts/flowlayout/main.cpp b/examples/widgets/layouts/flowlayout/main.cpp index 99725195e5..bbc78ccda3 100644 --- a/examples/widgets/layouts/flowlayout/main.cpp +++ b/examples/widgets/layouts/flowlayout/main.cpp @@ -47,7 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - +//! [1] #include <QApplication> #include "window.h" @@ -59,3 +59,4 @@ int main(int argc, char *argv[]) window.show(); return app.exec(); } +//! [1] diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 9143e04d45..ebf9864b15 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -48,9 +48,7 @@ #include <errno.h> -#if QT_CONFIG(getentropy) -# include <sys/random.h> -#elif !defined(Q_OS_BSD4) && !defined(Q_OS_WIN) +#if !QT_CONFIG(getentropy) && !defined(Q_OS_BSD4) && !defined(Q_OS_WIN) # include "qdeadlinetimer.h" # include "qhashfunctions.h" diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index d043b3aea5..06eacf5455 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -750,13 +750,47 @@ QString QDir::filePath(const QString &fileName) const QString QDir::absoluteFilePath(const QString &fileName) const { const QDirPrivate* d = d_ptr.constData(); - if (isAbsolutePath(fileName)) + // Don't trust our own isAbsolutePath(); Q_OS_WIN needs a drive. + if (QFileSystemEntry(fileName).isAbsolute()) return fileName; d->resolveAbsoluteEntry(); const QString absoluteDirPath = d->absoluteDirEntry.filePath(); if (fileName.isEmpty()) return absoluteDirPath; +#ifdef Q_OS_WIN + // Handle the "absolute except for drive" case (i.e. \blah not c:\blah): + int size = absoluteDirPath.length(); + if ((fileName.startsWith(QLatin1Char('/')) + || fileName.startsWith(QLatin1Char('\\'))) + && size > 1) { + // Combine absoluteDirPath's drive with fileName + int drive = 2; // length of drive prefix + if (Q_UNLIKELY(absoluteDirPath.at(1).unicode() != ':')) { + // Presumably, absoluteDirPath is an UNC path; use its //server/share + // part as "drive" - it's as sane a thing as we can do. + for (int i = 2; i-- > 0; ) { // Scan two "path fragments": + while (drive < size && absoluteDirPath.at(drive).unicode() == '/') + drive++; + if (drive >= size) { + qWarning("Base directory starts with neither a drive nor a UNC share: %s", + qPrintable(QDir::toNativeSeparators(absoluteDirPath))); + return QString(); + } + while (drive < size && absoluteDirPath.at(drive).unicode() != '/') + drive++; + } + // We'll append fileName, which starts with a slash; so omit trailing slash: + if (absoluteDirPath.at(drive).unicode() == '/') + drive--; + } else if (!absoluteDirPath.at(0).isLetter()) { + qWarning("Base directory's drive is not a letter: %s", + qPrintable(QDir::toNativeSeparators(absoluteDirPath))); + return QString(); + } + return absoluteDirPath.leftRef(drive) % fileName; + } +#endif // Q_OS_WIN if (!absoluteDirPath.endsWith(QLatin1Char('/'))) return absoluteDirPath % QLatin1Char('/') % fileName; return absoluteDirPath % fileName; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 2a42ad42f9..5cc3a5937e 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -91,26 +91,35 @@ extern "C" NSString *NSTemporaryDirectory(); # include <sys/syscall.h> # include <sys/sendfile.h> # include <linux/fs.h> +# include <linux/stat.h> // in case linux/fs.h is too old and doesn't define it: #ifndef FICLONE # define FICLONE _IOW(0x94, 9, int) #endif -# if !QT_CONFIG(renameat2) && defined(SYS_renameat2) +# if defined(Q_OS_ANDROID) +// renameat2() and statx() are disabled on Android because quite a few systems +// come with sandboxes that kill applications that make system calls outside a +// whitelist and several Android vendors can't be bothered to update the list. +# undef SYS_renameat2 +# undef SYS_statx +# undef STATX_BASIC_STATS +# else +# if !QT_CONFIG(renameat2) && defined(SYS_renameat2) static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newpath, unsigned flags) { return syscall(SYS_renameat2, oldfd, oldpath, newfd, newpath, flags); } -# endif +# endif -# if !QT_CONFIG(statx) && defined(SYS_statx) && QT_HAS_INCLUDE(<linux/stat.h>) -# include <linux/stat.h> +# if !QT_CONFIG(statx) && defined(SYS_statx) static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struct statx *statxbuf) { return syscall(SYS_statx, dirfd, pathname, flag, mask, statxbuf); } -# endif +# endif +# endif // !Q_OS_ANDROID #endif -#ifndef STATX_BASIC_STATS -struct statx { mode_t stx_mode; }; +#ifndef STATX_ALL +struct statx { mode_t stx_mode; }; // dummy #endif QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 04c9a9bcba..712e8bbcab 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -599,7 +599,7 @@ void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *liste jobject QtAndroidPrivate::callOnBindListener(jobject intent) { QMutexLocker lock(g_onBindListenerMutex); - if (g_onBindListener) + if (*g_onBindListener) return (*g_onBindListener)->onBind(intent); return nullptr; } diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 96299b9eaf..f77831c703 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3896,7 +3896,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) \sa setValue(), value() */ -/*! \fn static inline QVariant fromStdVariant(const std::variant<T, Types...> &value) +/*! \fn template<typename... Types> QVariant QVariant::fromStdVariant(const std::variant<Types...> &value) \since 5.11 Returns a QVariant with the type and value of the active variant of \a value. If diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index b515dfa099..1dc4b56e9b 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -359,7 +359,7 @@ class Q_CORE_EXPORT QVariant static inline QVariant fromValue(const T &value) { return qVariantFromValue(value); } -#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L +#if defined(Q_CLANG_QDOC) || (QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L) template<typename... Types> static inline QVariant fromStdVariant(const std::variant<Types...> &value) { diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 4ae4e687a0..7b0e691127 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -4409,7 +4409,6 @@ QByteArray &QByteArray::setRawData(const char *data, uint size) } else { d->offset = sizeof(QByteArrayData); d->size = 0; - *d->data() = 0; } } return *this; diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index cf3d712421..c3a264f1e8 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -222,6 +222,9 @@ void QOpenGLWindowPrivate::initialize() if (context) return; + if (!q->handle()) + qWarning("Attempted to initialize QOpenGLWindow without a platform window"); + context.reset(new QOpenGLContext); context->setShareContext(shareContext); context->setFormat(q->requestedFormat()); diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index e5cd0be519..1b964ba913 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -251,7 +251,7 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt: { Q_ASSERT(window); if (oldState < Qt::WindowNoState) - oldState = window->windowState(); + oldState = window->windowStates(); QWindowSystemInterfacePrivate::WindowStateChangedEvent *e = new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState, Qt::WindowStates(oldState)); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index ed9d00f4a7..efd9b0c146 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5489,6 +5489,8 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL // nothing } else if (coverage == 255) { *dst = src; + } else if (!colorProfile) { + *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage); } else { if (*dst >= 0xff000000) { grayBlendPixel(dst, coverage, srcLinear, colorProfile); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index f7578a3c57..33fde8c61a 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2341,8 +2341,12 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) { QRectF targetBounds = s->matrix.mapRect(r); - bool exceedsPrecision = targetBounds.width() > 0x7fff - || targetBounds.height() > 0x7fff; + bool exceedsPrecision = r.width() > 0x7fff + || r.height() > 0x7fff + || targetBounds.width() > 0x7fff + || targetBounds.height() > 0x7fff + || s->matrix.m11() >= 512 + || s->matrix.m22() >= 512; if (!exceedsPrecision && d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) { if (s->matrix.type() > QTransform::TxScale) { @@ -4639,9 +4643,13 @@ void QSpanData::setupMatrix(const QTransform &matrix, int bilin) bilinear = bilin; const bool affine = inv.isAffine(); + const qreal f1 = m11 * m11 + m21 * m21; + const qreal f2 = m12 * m12 + m22 * m22; fast_matrix = affine - && m11 * m11 + m21 * m21 < 1e4 - && m12 * m12 + m22 * m22 < 1e4 + && f1 < 1e4 + && f2 < 1e4 + && f1 > (1.0 / 65536) + && f2 > (1.0 / 65536) && qAbs(dx) < 1e4 && qAbs(dy) < 1e4; diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index e0c705f97e..116a6693c4 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -876,12 +876,12 @@ void QSslConfiguration::setDiffieHellmanParameters(const QSslDiffieHellmanParame Returns the backend-specific configuration. - Only options set by addBackendConfig() or setBackendConfig() will be + Only options set by addBackendConfiguration() or setBackendConfiguration() will be returned. The internal standard configuration of the backend is not reported. - \sa setBackendConfigOption(), setBackendConfig() + \sa setBackendConfigurationOption(), setBackendConfiguration() */ -QMap<QByteArray, QVariant> QSslConfiguration::backendConfig() const +QMap<QByteArray, QVariant> QSslConfiguration::backendConfiguration() const { return d->backendConfig; } @@ -902,9 +902,9 @@ QMap<QByteArray, QVariant> QSslConfiguration::backendConfig() const configuration. Using the backend-specific configuration to set a general configuration option again will overwrite the general configuration option. - \sa backendConfig(), setBackendConfig() + \sa backendConfiguration(), setBackendConfiguration() */ -void QSslConfiguration::setBackendConfigOption(const QByteArray &name, const QVariant &value) +void QSslConfiguration::setBackendConfigurationOption(const QByteArray &name, const QVariant &value) { d->backendConfig[name] = value; } @@ -914,13 +914,13 @@ void QSslConfiguration::setBackendConfigOption(const QByteArray &name, const QVa Sets or clears the backend-specific configuration. - Without a \a backendConfig parameter this function will clear the + Without a \a backendConfiguration parameter this function will clear the backend-specific configuration. More information about the supported - options is available in the documentation of addBackendConfig(). + options is available in the documentation of addBackendConfiguration(). - \sa backendConfig(), setBackendConfigOption() + \sa backendConfiguration(), setBackendConfigurationOption() */ -void QSslConfiguration::setBackendConfig(const QMap<QByteArray, QVariant> &backendConfig) +void QSslConfiguration::setBackendConfiguration(const QMap<QByteArray, QVariant> &backendConfig) { d->backendConfig = backendConfig; } diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h index b3264126dd..a5561d9828 100644 --- a/src/network/ssl/qsslconfiguration.h +++ b/src/network/ssl/qsslconfiguration.h @@ -150,9 +150,9 @@ public: QSslDiffieHellmanParameters diffieHellmanParameters() const; void setDiffieHellmanParameters(const QSslDiffieHellmanParameters &dhparams); - QMap<QByteArray, QVariant> backendConfig() const; - void setBackendConfigOption(const QByteArray &name, const QVariant &value); - void setBackendConfig(const QMap<QByteArray, QVariant> &backendConfig = QMap<QByteArray, QVariant>()); + QMap<QByteArray, QVariant> backendConfiguration() const; + void setBackendConfigurationOption(const QByteArray &name, const QVariant &value); + void setBackendConfiguration(const QMap<QByteArray, QVariant> &backendConfig = QMap<QByteArray, QVariant>()); static QSslConfiguration defaultConfiguration(); static void setDefaultConfiguration(const QSslConfiguration &configuration); diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 386c280659..41b759364b 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -245,7 +245,7 @@ QString QSslContext::errorString() const // static void QSslContext::applyBackendConfig(QSslContext *sslContext) { - if (sslContext->sslConfiguration.backendConfig().isEmpty()) + if (sslContext->sslConfiguration.backendConfiguration().isEmpty()) return; #if OPENSSL_VERSION_NUMBER >= 0x10002000L @@ -255,7 +255,7 @@ void QSslContext::applyBackendConfig(QSslContext *sslContext) q_SSL_CONF_CTX_set_ssl_ctx(cctx.data(), sslContext->ctx); q_SSL_CONF_CTX_set_flags(cctx.data(), SSL_CONF_FLAG_FILE); - const auto &backendConfig = sslContext->sslConfiguration.backendConfig(); + const auto &backendConfig = sslContext->sslConfiguration.backendConfiguration(); for (auto i = backendConfig.constBegin(); i != backendConfig.constEnd(); ++i) { if (!i.value().canConvert(QMetaType::QByteArray)) { sslContext->errorCode = QSslError::UnspecifiedError; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 833d676192..4273904c12 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -922,7 +922,7 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration) d->configuration.peerVerifyDepth = configuration.peerVerifyDepth(); d->configuration.peerVerifyMode = configuration.peerVerifyMode(); d->configuration.protocol = configuration.protocol(); - d->configuration.backendConfig = configuration.backendConfig(); + d->configuration.backendConfig = configuration.backendConfiguration(); d->configuration.sslOptions = configuration.d->sslOptions; d->configuration.sslSession = configuration.sessionTicket(); d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint(); diff --git a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp index de369e0b00..aa7bb102c6 100644 --- a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp +++ b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp @@ -134,6 +134,7 @@ messageDebugEntries[] = { {WM_XBUTTONUP, "WM_XBUTTONUP", true}, {WM_XBUTTONDBLCLK, "WM_XBUTTONDBLCLK", true}, {WM_MOUSEHWHEEL, "WM_MOUSEHWHEEL", true}, + {WM_GETOBJECT, "WM_GETOBJECT", true}, {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true}, {WM_INPUTLANGCHANGE, "WM_INPUTLANGCHANGE", true}, {WM_IME_NOTIFY, "WM_IME_NOTIFY", true}, @@ -162,6 +163,7 @@ messageDebugEntries[] = { {WM_GETMINMAXINFO, "WM_GETMINMAXINFO", true}, {WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING", true}, {WM_NCCREATE, "WM_NCCREATE", true}, + {WM_NCDESTROY, "WM_NCDESTROY", true}, {WM_NCCALCSIZE, "WM_NCCALCSIZE", true}, {WM_NCACTIVATE, "WM_NCACTIVATE", true}, {WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE", true}, @@ -180,7 +182,9 @@ messageDebugEntries[] = { {WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN", true}, {WM_DISPLAYCHANGE, "WM_DISPLAYCHANGE", true}, {WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD", true}, - {WM_THEMECHANGED, "WM_THEMECHANGED", true} + {WM_THEMECHANGED, "WM_THEMECHANGED", true}, + {0x90, "WM_UAHDESTROYWINDOW", true}, + {0x272, "WM_UNREGISTER_WINDOW_SERVICES", true} }; static inline const MessageDebugEntry *messageDebugEntry(UINT msg) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 85d213ad46..bbaaf43ebb 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -507,6 +507,8 @@ static void addExtraFallbacks(QStringList *fallbackList) // add Apple Symbols to cover those too. if (!fallbackList->contains(QStringLiteral("Apple Symbols"))) fallbackList->append(QStringLiteral("Apple Symbols")); +#else + Q_UNUSED(fallbackList) #endif } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 3d0dbd7b1a..20d6e6e8d4 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1364,9 +1364,10 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow); if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) { if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) { - qCDebug(lcQpaEvents) << "EVENT: hwd=" << hwnd << eventName << hex << "msg=0x" << message - << "et=0x" << et << dec << "wp=" << int(wParam) << "at" - << GET_X_LPARAM(lParam) << GET_Y_LPARAM(lParam) << "handled=" << handled; + qCDebug(lcQpaEvents).nospace() << "EVENT: hwd=" << hwnd << ' ' << eventName + << " msg=0x" << hex << message << " et=0x" << et << dec << " wp=" + << int(wParam) << " at " << GET_X_LPARAM(lParam) << ',' + << GET_Y_LPARAM(lParam) << " handled=" << handled; } } if (!handled) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 159e1250d0..9fff4b5e42 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1077,6 +1077,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, */ const char *QWindowsWindow::embeddedNativeParentHandleProperty = "_q_embedded_native_parent_handle"; +const char *QWindowsWindow::hasBorderInFullScreenProperty = "_q_has_border_in_fullscreen"; QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) : QWindowsBaseWindow(aWindow), @@ -1106,7 +1107,6 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) updateDropSite(window()->isTopLevel()); registerTouchWindow(); - setWindowState(aWindow->windowStates()); const qreal opacity = qt_window_private(aWindow)->opacity; if (!qFuzzyCompare(opacity, qreal(1.0))) setOpacity(opacity); @@ -1115,6 +1115,8 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) if (aWindow->isTopLevel()) setWindowIcon(aWindow->icon()); + if (aWindow->property(hasBorderInFullScreenProperty).toBool()) + setFlag(HasBorderInFullScreen); clearFlag(WithinCreate); } @@ -1133,9 +1135,11 @@ void QWindowsWindow::initialize() QWindowCreationContextPtr creationContext = QWindowsContext::instance()->setWindowCreationContext(QWindowCreationContextPtr()); + QWindow *w = window(); + setWindowState(w->windowStates()); + // Trigger geometry change (unless it has a special state in which case setWindowState() // will send the message) and screen change signals of QWindow. - QWindow *w = window(); if (w->type() != Qt::Desktop) { const Qt::WindowState state = w->windowState(); if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen @@ -2662,15 +2666,26 @@ void QWindowsWindow::setHasBorderInFullScreenStatic(QWindow *window, bool border if (QPlatformWindow *handle = window->handle()) static_cast<QWindowsWindow *>(handle)->setHasBorderInFullScreen(border); else - qWarning("%s invoked without window handle; call has no effect.", Q_FUNC_INFO); + window->setProperty(hasBorderInFullScreenProperty, QVariant(border)); } void QWindowsWindow::setHasBorderInFullScreen(bool border) { + if (testFlag(HasBorderInFullScreen) == border) + return; if (border) setFlag(HasBorderInFullScreen); else clearFlag(HasBorderInFullScreen); + // Directly apply the flag in case we are fullscreen. + if (m_windowState == Qt::WindowFullScreen) { + LONG_PTR style = GetWindowLongPtr(handle(), GWL_STYLE); + if (border) + style |= WS_BORDER; + else + style &= ~WS_BORDER; + SetWindowLongPtr(handle(), GWL_STYLE, style); + } } QString QWindowsWindow::formatWindowTitle(const QString &title) diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 8d29b871bf..fe2518e329 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -340,6 +340,7 @@ public: static QString formatWindowTitle(const QString &title); static const char *embeddedNativeParentHandleProperty; + static const char *hasBorderInFullScreenProperty; private: inline void show_sys() const; diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 6ae52d9fd3..70d1757af4 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -74,7 +74,9 @@ class QXcbShmImage : public QXcbObject { public: QXcbShmImage(QXcbScreen *connection, const QSize &size, uint depth, QImage::Format format); - ~QXcbShmImage() { destroy(); } + ~QXcbShmImage() { destroy(true); } + + void resize(const QSize &size); void flushScrolledRegion(bool clientSideScroll); @@ -95,14 +97,18 @@ private: void createShmSegment(size_t segmentSize); void destroyShmSegment(size_t segmentSize); - void destroy(); + void create(const QSize &size, const xcb_format_t *fmt, QImage::Format format); + void destroy(bool destroyShm); void ensureGC(xcb_drawable_t dst); void shmPutImage(xcb_drawable_t drawable, const QRegion ®ion, const QPoint &offset = QPoint()); void flushPixmap(const QRegion ®ion, bool fullRegion = false); void setClip(const QRegion ®ion); + xcb_window_t m_screen_root; + xcb_shm_segment_info_t m_shm_info; + size_t m_segmentSize; xcb_image_t *m_xcb_image; @@ -171,6 +177,8 @@ static inline size_t imageDataSize(const xcb_image_t *image) QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format) : QXcbObject(screen->connection()) + , m_screen_root(screen->screen()->root) + , m_segmentSize(0) , m_graphics_buffer(nullptr) , m_gc(0) , m_gc_drawable(0) @@ -180,6 +188,27 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI const xcb_format_t *fmt = connection()->formatForDepth(depth); Q_ASSERT(fmt); + m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; + if (!m_hasAlpha) + format = qt_maybeAlphaVersionWithSameDepth(format); + + memset(&m_shm_info, 0, sizeof m_shm_info); + create(size, fmt, format); +} + +void QXcbShmImage::resize(const QSize &size) +{ + xcb_format_t fmt; + fmt.depth = m_xcb_image->depth; + fmt.bits_per_pixel = m_xcb_image->bpp; + fmt.scanline_pad = m_xcb_image->scanline_pad; + memset(fmt.pad0, 0, sizeof(fmt.pad0)); + destroy(false); + create(size, &fmt, m_qimage.format()); +} + +void QXcbShmImage::create(const QSize &size, const xcb_format_t *fmt, QImage::Format format) +{ m_xcb_image = xcb_image_create(size.width(), size.height(), XCB_IMAGE_FORMAT_Z_PIXMAP, fmt->scanline_pad, @@ -192,14 +221,16 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI if (!segmentSize) return; - createShmSegment(segmentSize); + if (hasShm() && m_segmentSize > 0 && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize)) + destroyShmSegment(m_segmentSize); + if (!hasShm() && connection()->hasShm()) + { + qCDebug(lcQpaXcb) << "creating shared memory" << segmentSize << "for" << size << "depth" << fmt->depth << "bits" << fmt->bits_per_pixel; + createShmSegment(segmentSize); + } m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize); - m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; - if (!m_hasAlpha) - format = qt_maybeAlphaVersionWithSameDepth(format); - m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format); m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage); @@ -207,10 +238,36 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI xcb_create_pixmap(xcb_connection(), m_xcb_image->depth, m_xcb_pixmap, - screen->screen()->root, + m_screen_root, m_xcb_image->width, m_xcb_image->height); } +void QXcbShmImage::destroy(bool destroyShm) +{ + if (m_xcb_image->data) { + if (m_shm_info.shmaddr) { + if (destroyShm) + destroyShmSegment(m_segmentSize); + } else { + free(m_xcb_image->data); + } + } + + xcb_image_destroy(m_xcb_image); + + if (m_gc) { + xcb_free_gc(xcb_connection(), m_gc); + m_gc = 0; + } + m_gc_drawable = 0; + + delete m_graphics_buffer; + m_graphics_buffer = nullptr; + + xcb_free_pixmap(xcb_connection(), m_xcb_pixmap); + m_xcb_pixmap = 0; +} + void QXcbShmImage::flushScrolledRegion(bool clientSideScroll) { if (m_clientSideScroll == clientSideScroll) @@ -261,10 +318,8 @@ void QXcbShmImage::flushScrolledRegion(bool clientSideScroll) void QXcbShmImage::createShmSegment(size_t segmentSize) { - m_shm_info.shmaddr = nullptr; - - if (!connection()->hasShm()) - return; + Q_ASSERT(connection()->hasShm()); + Q_ASSERT(m_segmentSize == 0); #ifdef XCB_USE_SHM_FD if (connection()->hasShmFd()) { @@ -302,6 +357,8 @@ void QXcbShmImage::createShmSegment(size_t segmentSize) close(fds[0]); m_shm_info.shmseg = seg; m_shm_info.shmaddr = static_cast<quint8 *>(addr); + + m_segmentSize = segmentSize; } else #endif { @@ -338,6 +395,8 @@ void QXcbShmImage::createShmSegment(size_t segmentSize) m_shm_info.shmseg = seg; m_shm_info.shmid = id; // unused m_shm_info.shmaddr = static_cast<quint8 *>(addr); + + m_segmentSize = segmentSize; } } @@ -350,6 +409,7 @@ void QXcbShmImage::destroyShmSegment(size_t segmentSize) xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie); if (error) connection()->printXcbError("QXcbShmImage: xcb_shm_detach() failed with error", error); + m_shm_info.shmseg = 0; #ifdef XCB_USE_SHM_FD if (connection()->hasShmFd()) { @@ -364,7 +424,11 @@ void QXcbShmImage::destroyShmSegment(size_t segmentSize) qWarning("QXcbShmImage: shmdt() failed (%d: %s) for %p", errno, strerror(errno), m_shm_info.shmaddr); } + m_shm_info.shmid = 0; // unused } + m_shm_info.shmaddr = nullptr; + + m_segmentSize = 0; } extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); @@ -413,26 +477,6 @@ bool QXcbShmImage::scroll(const QRegion &area, int dx, int dy) return true; } -void QXcbShmImage::destroy() -{ - if (m_xcb_image->data) { - if (m_shm_info.shmaddr) - destroyShmSegment(imageDataSize(m_xcb_image)); - else - free(m_xcb_image->data); - } - - xcb_image_destroy(m_xcb_image); - - if (m_gc) - xcb_free_gc(xcb_connection(), m_gc); - delete m_graphics_buffer; - m_graphics_buffer = nullptr; - - xcb_free_pixmap(xcb_connection(), m_xcb_pixmap); - m_xcb_pixmap = 0; -} - void QXcbShmImage::ensureGC(xcb_drawable_t dst) { if (m_gc_drawable != dst) { @@ -805,7 +849,6 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) if (m_image && size == m_image->size()) return; - QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle()); QPlatformWindow *pw = window()->handle(); if (!pw) { window()->create(); @@ -813,8 +856,13 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) } QXcbWindow* win = static_cast<QXcbWindow *>(pw); - delete m_image; - m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); + if (m_image) { + m_image->resize(size); + } else { + QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle()); + m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); + } + // Slow path for bgr888 VNC: Create an additional image, paint into that and // swap R and B while copying to m_image after each paint. if (win->imageNeedsRgbSwap()) { diff --git a/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp b/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp index 04abd707e1..6c5e1389cf 100644 --- a/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp +++ b/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp @@ -95,41 +95,25 @@ QFlatpakTheme::QFlatpakTheme() QPlatformMenuItem* QFlatpakTheme::createPlatformMenuItem() const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createPlatformMenuItem(); - - return QPlatformTheme::createPlatformMenuItem(); + return d->baseTheme->createPlatformMenuItem(); } QPlatformMenu* QFlatpakTheme::createPlatformMenu() const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createPlatformMenu(); - - return QPlatformTheme::createPlatformMenu(); + return d->baseTheme->createPlatformMenu(); } QPlatformMenuBar* QFlatpakTheme::createPlatformMenuBar() const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createPlatformMenuBar(); - - return QFlatpakTheme::createPlatformMenuBar(); + return d->baseTheme->createPlatformMenuBar(); } void QFlatpakTheme::showPlatformMenuBar() { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->showPlatformMenuBar(); - - return QFlatpakTheme::showPlatformMenuBar(); + return d->baseTheme->showPlatformMenuBar(); } bool QFlatpakTheme::usePlatformNativeDialog(DialogType type) const @@ -139,10 +123,7 @@ bool QFlatpakTheme::usePlatformNativeDialog(DialogType type) const if (type == FileDialog) return true; - if (d->baseTheme) - return d->baseTheme->usePlatformNativeDialog(type); - - return QFlatpakTheme::usePlatformNativeDialog(type); + return d->baseTheme->usePlatformNativeDialog(type); } QPlatformDialogHelper* QFlatpakTheme::createPlatformDialogHelper(DialogType type) const @@ -152,103 +133,64 @@ QPlatformDialogHelper* QFlatpakTheme::createPlatformDialogHelper(DialogType type if (type == FileDialog) return new QFlatpakFileDialog; - if (d->baseTheme) - return d->baseTheme->createPlatformDialogHelper(type); - - return QFlatpakTheme::createPlatformDialogHelper(type); + return d->baseTheme->createPlatformDialogHelper(type); } #ifndef QT_NO_SYSTEMTRAYICON QPlatformSystemTrayIcon* QFlatpakTheme::createPlatformSystemTrayIcon() const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createPlatformSystemTrayIcon(); - - return QPlatformTheme::createPlatformSystemTrayIcon(); + return d->baseTheme->createPlatformSystemTrayIcon(); } #endif const QPalette *QFlatpakTheme::palette(Palette type) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->palette(type); - - return QPlatformTheme::palette(type); + return d->baseTheme->palette(type); } const QFont* QFlatpakTheme::font(Font type) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->font(type); - - return QPlatformTheme::font(type); + return d->baseTheme->font(type); } QVariant QFlatpakTheme::themeHint(ThemeHint hint) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->themeHint(hint); - - return QPlatformTheme::themeHint(hint); + return d->baseTheme->themeHint(hint); } QPixmap QFlatpakTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->standardPixmap(sp, size); - - return QPlatformTheme::standardPixmap(sp, size); + return d->baseTheme->standardPixmap(sp, size); } QIcon QFlatpakTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->fileIcon(fileInfo, iconOptions); - - return QPlatformTheme::fileIcon(fileInfo, iconOptions); + return d->baseTheme->fileIcon(fileInfo, iconOptions); } QIconEngine * QFlatpakTheme::createIconEngine(const QString &iconName) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createIconEngine(iconName); - - return QPlatformTheme::createIconEngine(iconName); + return d->baseTheme->createIconEngine(iconName); } QList<QKeySequence> QFlatpakTheme::keyBindings(QKeySequence::StandardKey key) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->keyBindings(key); - - return QPlatformTheme::keyBindings(key); + return d->baseTheme->keyBindings(key); } QString QFlatpakTheme::standardButtonText(int button) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->standardButtonText(button); - - return QPlatformTheme::standardButtonText(button); + return d->baseTheme->standardButtonText(button); } QT_END_NAMESPACE diff --git a/src/widgets/doc/images/graphicsflowlayout.png b/src/widgets/doc/images/graphicsflowlayout.png Binary files differnew file mode 100644 index 0000000000..ea70e102c3 --- /dev/null +++ b/src/widgets/doc/images/graphicsflowlayout.png diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index b7048d1616..00e9ff7400 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -1175,9 +1175,10 @@ bool QHeaderView::sectionsMovable() const */ /*! - \since 5.10 + \property QHeaderView::firstSectionMovable + \brief Whether the first column can be moved by the user - If \a movable is true, the first column can be moved by the user. + This property controls whether the first column can be moved by the user. In a QTreeView, the first column holds the tree structure and is therefore non-movable by default, even after setSectionsMovable(true). @@ -1186,8 +1187,11 @@ bool QHeaderView::sectionsMovable() const In such a scenario, it is recommended to call QTreeView::setRootIsDecorated(false) as well. - This method has no effect unless setSectionsMovable(true) is called as well. + Setting it to true has no effect unless setSectionsMovable(true) is called + as well. + \sa setSectionsMovable() + \since 5.11 */ void QHeaderView::setFirstSectionMovable(bool movable) { @@ -1195,13 +1199,7 @@ void QHeaderView::setFirstSectionMovable(bool movable) d->allowUserMoveOfSection0 = movable; } -/*! - \since 5.10 - - Returns \c true if the first column can be moved by the user, - when this header is used in a QTreeView. -*/ -bool QHeaderView::firstSectionMovable() const +bool QHeaderView::isFirstSectionMovable() const { Q_D(const QHeaderView); return d->allowUserMoveOfSection0; diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h index c09081cd80..7e950add1f 100644 --- a/src/widgets/itemviews/qheaderview.h +++ b/src/widgets/itemviews/qheaderview.h @@ -53,6 +53,7 @@ class QStyleOptionHeader; class Q_WIDGETS_EXPORT QHeaderView : public QAbstractItemView { Q_OBJECT + Q_PROPERTY(bool firstSectionMovable READ isFirstSectionMovable WRITE setFirstSectionMovable) Q_PROPERTY(bool showSortIndicator READ isSortIndicatorShown WRITE setSortIndicatorShown) Q_PROPERTY(bool highlightSections READ highlightSections WRITE setHighlightSections) Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection) @@ -119,7 +120,7 @@ public: inline QT_DEPRECATED bool isMovable() const { return sectionsMovable(); } #endif void setFirstSectionMovable(bool movable); - bool firstSectionMovable() const; + bool isFirstSectionMovable() const; void setSectionsClickable(bool clickable); bool sectionsClickable() const; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 4cf52f994a..39540cf898 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -113,8 +113,10 @@ static void initResources() { Q_INIT_RESOURCE(qstyle); - Q_INIT_RESOURCE(qmessagebox); +#if QT_CONFIG(messagebox) + Q_INIT_RESOURCE(qmessagebox); +#endif } QT_BEGIN_NAMESPACE diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 138733476f..923245c53c 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5457,11 +5457,11 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP setSystemClip(pdev->paintEngine(), pdev->devicePixelRatioF(), rgn.translated(offset)); QPainter p(pdev); p.translate(offset); - context.painter = context.sharedPainter = &p; + context.painter = &p; graphicsEffect->draw(&p); setSystemClip(pdev->paintEngine(), 1, QRegion()); } else { - context.painter = context.sharedPainter = sharedPainter; + context.painter = sharedPainter; if (sharedPainter->worldTransform() != sourced->lastEffectTransform) { sourced->invalidateCache(); sourced->lastEffectTransform = sharedPainter->worldTransform(); diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 9d47bb2884..734b26cd65 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -1384,16 +1384,22 @@ void tst_QDir::absoluteFilePath_data() QTest::addColumn<QString>("fileName"); QTest::addColumn<QString>("expectedFilePath"); - QTest::newRow("0") << "/etc" << "/passwd" << "/passwd"; - QTest::newRow("1") << "/etc" << "passwd" << "/etc/passwd"; - QTest::newRow("2") << "/" << "passwd" << "/passwd"; - QTest::newRow("3") << "relative" << "path" << QDir::currentPath() + "/relative/path"; - QTest::newRow("4") << "" << "" << QDir::currentPath(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - QTest::newRow("5") << "//machine" << "share" << "//machine/share"; + QTest::newRow("UNC") << "//machine" << "share" << "//machine/share"; + QTest::newRow("Drive") << "c:/side/town" << "/my/way/home" << "c:/my/way/home"; +#define DRIVE "Q:" +#else +#define DRIVE #endif + QTest::newRow("0") << DRIVE "/etc" << "/passwd" << DRIVE "/passwd"; + QTest::newRow("1") << DRIVE "/etc" << "passwd" << DRIVE "/etc/passwd"; + QTest::newRow("2") << DRIVE "/" << "passwd" << DRIVE "/passwd"; + QTest::newRow("3") << "relative" << "path" << QDir::currentPath() + "/relative/path"; + QTest::newRow("4") << "" << "" << QDir::currentPath(); + QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar"; +#undef DRIVE } void tst_QDir::absoluteFilePath() diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index 9a338ad55a..fedb88f1a8 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -528,8 +528,16 @@ void tst_QPixmap::fill_transparent() QVERIFY(pixmap.hasAlphaChannel()); } +static bool isPlatformWayland() +{ + return QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive); +} + void tst_QPixmap::mask() { + if (isPlatformWayland()) + QSKIP("Wayland: This fails. See QTBUG-66983."); + QPixmap pm(100, 100); QBitmap bm(100, 100); @@ -792,6 +800,9 @@ void tst_QPixmap::convertFromImageNoDetach() void tst_QPixmap::convertFromImageNoDetach2() { + if (isPlatformWayland()) + QSKIP("Wayland: This fails. See QTBUG-66984."); + QPixmap randomPixmap(10, 10); if (randomPixmap.handle()->classId() != QPlatformPixmap::RasterClass) QSKIP("Test only valid for raster pixmaps"); @@ -1466,6 +1477,9 @@ void tst_QPixmap::fromImageReaderAnimatedGif() void tst_QPixmap::task_246446() { + if (isPlatformWayland()) + QSKIP("Wayland: This fails. See QTBUG-66985."); + // This crashed without the bugfix in 246446 QPixmap pm(10, 10); pm.fill(Qt::transparent); // force 32-bit depth diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 4f27aeb899..b5a69d920a 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -35,9 +35,12 @@ #include <QtGui/QFont> #include <QtGui/QPalette> #include <QtGui/QStyleHints> +#include <qpa/qplatformintegration.h> #include <qpa/qwindowsysteminterface.h> #include <qgenericplugin.h> +#include <private/qguiapplication_p.h> + #if defined(Q_OS_QNX) #include <QOpenGLContext> #endif @@ -203,8 +206,8 @@ void tst_QGuiApplication::focusObject() int argc = 0; QGuiApplication app(argc, 0); - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) + QSKIP("QWindow::requestActivate() is not supported."); QObject obj1, obj2, obj3; const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry(); @@ -374,8 +377,8 @@ void tst_QGuiApplication::changeFocusWindow() int argc = 0; QGuiApplication app(argc, 0); - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) + QSKIP("QWindow::requestActivate() is not supported."); const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry(); diff --git a/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp b/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp index 509f8bd45f..15c905f943 100644 --- a/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp +++ b/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp @@ -186,8 +186,8 @@ void tst_qinputmethod::cursorRectangle() { QCOMPARE(qApp->inputMethod()->cursorRectangle(), QRectF()); - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) + QSKIP("QWindow::requestActivate() is not supported."); DummyWindow window; window.show(); @@ -284,8 +284,8 @@ void tst_qinputmethod::inputDirection() void tst_qinputmethod::inputMethodAccepted() { - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) + QSKIP("QWindow::requestActivate() is not supported."); if (!QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive) || !QGuiApplication::platformName().compare(QLatin1String("offscreen"), Qt::CaseInsensitive)) { diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index 706c66ef14..d16d95500b 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -317,9 +317,6 @@ void tst_QTouchEvent::touchDisabledByDefault() void tst_QTouchEvent::touchEventAcceptedByDefault() { - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); - // QWidget { // enabling touch events should automatically accept touch events @@ -606,9 +603,6 @@ QPointF normalized(const QPointF &pos, const QRectF &rect) void tst_QTouchEvent::basicRawEventTranslation() { - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); - tst_QTouchEventWidget touchWidget; touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); @@ -733,9 +727,6 @@ void tst_QTouchEvent::basicRawEventTranslation() void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() { - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); - tst_QTouchEventWidget touchWidget; touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); @@ -962,9 +953,6 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() { - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); - tst_QTouchEventWidget touchWidget; touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); @@ -1191,9 +1179,6 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() void tst_QTouchEvent::basicRawEventTranslationOfIds() { - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); - tst_QTouchEventWidget touchWidget; touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); @@ -1311,9 +1296,6 @@ void tst_QTouchEvent::basicRawEventTranslationOfIds() void tst_QTouchEvent::deleteInEventHandler() { - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); - // QWidget { QWidget window; @@ -1463,9 +1445,6 @@ void tst_QTouchEvent::deleteInEventHandler() void tst_QTouchEvent::deleteInRawEventTranslation() { - if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) - QSKIP("Wayland: This fails. Figure out why."); - tst_QTouchEventWidget touchWidget; touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index f77afd2364..1332b369e7 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -4016,12 +4016,12 @@ void tst_QSslSocket::signatureAlgorithm() SslServer server; server.protocol = serverProtocol; server.config.setCiphers({QSslCipher("ECDHE-RSA-AES256-SHA")}); - server.config.setBackendConfigOption(QByteArrayLiteral("SignatureAlgorithms"), serverSigAlgPairs.join(':')); + server.config.setBackendConfigurationOption(QByteArrayLiteral("SignatureAlgorithms"), serverSigAlgPairs.join(':')); QVERIFY(server.listen()); QSslConfiguration clientConfig = QSslConfiguration::defaultConfiguration(); clientConfig.setProtocol(clientProtocol); - clientConfig.setBackendConfigOption(QByteArrayLiteral("SignatureAlgorithms"), clientSigAlgPairs.join(':')); + clientConfig.setBackendConfigurationOption(QByteArrayLiteral("SignatureAlgorithms"), clientSigAlgPairs.join(':')); QSslSocket client; client.setSslConfiguration(clientConfig); socket = &client; diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index a959a71749..c059b83511 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -257,7 +257,7 @@ def main(name, *args): # Avoid interference from any qtlogging.ini files, e.g. in # /etc/xdg/QtProject/, (must match tst_selftests.cpp's # processEnvironment()'s value): - QT_LOGGING_RULES = '*.debug=true;qt.qpa.screen=false') + QT_LOGGING_RULES = '*.debug=true;qt.*=false') herePath = os.getcwd() cleaner = Cleaner(herePath, name) diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 8ac2ca7b90..1da1787c1d 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -417,7 +417,6 @@ tst_Selftests::tst_Selftests() void tst_Selftests::initTestCase() { QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString())); - qputenv("QT_LOGGING_RULES", QByteArrayLiteral("*.debug=false")); // Silence any debug output //Detect the location of the sub programs QString subProgram = QLatin1String("float/float"); #if defined(Q_OS_WIN) @@ -657,7 +656,7 @@ static QProcessEnvironment processEnvironment() // Avoid interference from any qtlogging.ini files, e.g. in /etc/xdg/QtProject/: result.insert(QStringLiteral("QT_LOGGING_RULES"), // Must match generate_expected_output.py's main()'s value: - QStringLiteral("*.debug=true;qt.qpa.screen=false")); + QStringLiteral("*.debug=true;qt.*=false")); } return result; } diff --git a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp index dfe5baba71..a1cb729849 100644 --- a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp @@ -52,7 +52,6 @@ private slots: void boundingRect2(); void draw(); void opacity(); - void nestedOpaqueOpacity(); void grayscale(); void colorize(); void drawPixmapItem(); @@ -408,26 +407,6 @@ void tst_QGraphicsEffect::opacity() QCOMPARE(effect->m_opacity, qreal(0.5)); } -void tst_QGraphicsEffect::nestedOpaqueOpacity() -{ - // QTBUG-60231: Nesting widgets with a QGraphicsEffect on a toplevel with - // QGraphicsOpacityEffect caused crashes due to constructing several - // QPainter instances on a device in the fast path for - // QGraphicsOpacityEffect::opacity=1 - QWidget topLevel; - topLevel.setWindowTitle(QTest::currentTestFunction()); - topLevel.resize(320, 200); - QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect; - opacityEffect->setOpacity(1); - topLevel.setGraphicsEffect(opacityEffect); - QWidget *child = new QWidget(&topLevel); - child->resize(topLevel.size() / 2); - QGraphicsDropShadowEffect *childEffect = new QGraphicsDropShadowEffect; - child->setGraphicsEffect(childEffect); - topLevel.show(); - QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); -} - void tst_QGraphicsEffect::grayscale() { if (qApp->desktop()->depth() < 24) diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 812ca4b223..74a2f7f2b6 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -544,11 +544,11 @@ void tst_QHeaderView::movable() view->setSectionsMovable(true); QCOMPARE(view->sectionsMovable(), true); - QCOMPARE(view->firstSectionMovable(), true); + QCOMPARE(view->isFirstSectionMovable(), true); view->setFirstSectionMovable(false); - QCOMPARE(view->firstSectionMovable(), false); + QCOMPARE(view->isFirstSectionMovable(), false); view->setFirstSectionMovable(true); - QCOMPARE(view->firstSectionMovable(), true); + QCOMPARE(view->isFirstSectionMovable(), true); } void tst_QHeaderView::clickable() diff --git a/tests/manual/qtabletevent/regular_widgets/main.cpp b/tests/manual/qtabletevent/regular_widgets/main.cpp index caf8c70c6f..c0366dea63 100644 --- a/tests/manual/qtabletevent/regular_widgets/main.cpp +++ b/tests/manual/qtabletevent/regular_widgets/main.cpp @@ -61,23 +61,38 @@ struct TabletPoint class ProximityEventFilter : public QObject { + Q_OBJECT public: explicit ProximityEventFilter(QObject *parent) : QObject(parent) { } - bool eventFilter(QObject *, QEvent *event) override - { - switch (event->type()) { - case QEvent::TabletEnterProximity: - case QEvent::TabletLeaveProximity: - qDebug() << event; - break; - default: - break; - } - return false; - } + bool eventFilter(QObject *, QEvent *event) override; + + static bool tabletPenProximity() { return m_tabletPenProximity; } + +signals: + void proximityChanged(); + +private: + static bool m_tabletPenProximity; }; +bool ProximityEventFilter::eventFilter(QObject *, QEvent *event) +{ + switch (event->type()) { + case QEvent::TabletEnterProximity: + case QEvent::TabletLeaveProximity: + ProximityEventFilter::m_tabletPenProximity = event->type() == QEvent::TabletEnterProximity; + emit proximityChanged(); + qDebug() << event; + break; + default: + break; + } + return false; +} + +bool ProximityEventFilter::m_tabletPenProximity = false; + class EventReportWidget : public QWidget { Q_OBJECT @@ -111,6 +126,7 @@ private: Qt::MouseButton m_lastButton = Qt::NoButton; QVector<TabletPoint> m_points; QVector<QPointF> m_touchPoints; + QPointF m_tabletPos; int m_tabletMoveCount = 0; int m_paintEventCount = 0; }; @@ -169,6 +185,13 @@ void EventReportWidget::paintEvent(QPaintEvent *) } } } + + // Draw haircross when tablet pen is in proximity + if (ProximityEventFilter::tabletPenProximity() && geom.contains(m_tabletPos)) { + p.setPen(Qt::black); + p.drawLine(QPointF(0, m_tabletPos.y()), QPointF(geom.width(), m_tabletPos.y())); + p.drawLine(QPointF(m_tabletPos.x(), 0), QPointF(m_tabletPos.x(), geom.height())); + } p.setPen(Qt::blue); for (QPointF t : m_touchPoints) { p.drawLine(t.x() - 40, t.y(), t.x() + 40, t.y()); @@ -181,20 +204,21 @@ void EventReportWidget::tabletEvent(QTabletEvent *event) { QWidget::tabletEvent(event); bool isMove = false; + m_tabletPos = event->posF(); switch (event->type()) { case QEvent::TabletMove: - m_points.push_back(TabletPoint(event->pos(), TabletMove, m_lastButton, event->pointerType(), event->pressure(), event->rotation())); + m_points.push_back(TabletPoint(m_tabletPos, TabletMove, m_lastButton, event->pointerType(), event->pressure(), event->rotation())); update(); isMove = true; ++m_tabletMoveCount; break; case QEvent::TabletPress: - m_points.push_back(TabletPoint(event->pos(), TabletButtonPress, event->button(), event->pointerType(), event->rotation())); + m_points.push_back(TabletPoint(m_tabletPos, TabletButtonPress, event->button(), event->pointerType(), event->rotation())); m_lastButton = event->button(); update(); break; case QEvent::TabletRelease: - m_points.push_back(TabletPoint(event->pos(), TabletButtonRelease, event->button(), event->pointerType(), event->rotation())); + m_points.push_back(TabletPoint(m_tabletPos, TabletButtonRelease, event->button(), event->pointerType(), event->rotation())); update(); break; default: @@ -253,10 +277,14 @@ void EventReportWidget::timerEvent(QTimerEvent *) int main(int argc, char *argv[]) { QApplication app(argc, argv); - app.installEventFilter(new ProximityEventFilter(&app)); + + ProximityEventFilter *proximityEventFilter = new ProximityEventFilter(&app); + app.installEventFilter(proximityEventFilter); QMainWindow mainWindow; mainWindow.setWindowTitle(QString::fromLatin1("Tablet Test %1").arg(QT_VERSION_STR)); EventReportWidget *widget = new EventReportWidget; + QObject::connect(proximityEventFilter, &ProximityEventFilter::proximityChanged, + widget, QOverload<void>::of(&QWidget::update)); widget->setMinimumSize(640, 480); QMenu *fileMenu = mainWindow.menuBar()->addMenu("File"); fileMenu->addAction("Clear", widget, &EventReportWidget::clearPoints); |