summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-05-27 09:16:56 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-05-27 09:17:14 +0200
commit65cfac73bd1c09eafadf57a3b7161f52b186c37d (patch)
treecb5c4f4fdc47ba9a54f22a996a6bff8b412a2c10 /src
parent9fc17c14fa682984742e8febd7551dd18bc36726 (diff)
parent761b71bd20524bc1e495508a52c38a0bc6679a06 (diff)
Merge "Merge remote-tracking branch 'origin/5.12' into 5.13"
Diffstat (limited to 'src')
-rw-r--r--src/corelib/doc/snippets/cmake-macros/examples.cmake26
-rw-r--r--src/corelib/doc/src/cmake-macros.qdoc212
-rw-r--r--src/corelib/kernel/qmetaobject.h3
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp8
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h172
-rw-r--r--src/gui/kernel/qplatformwindow.cpp12
-rw-r--r--src/gui/text/qtextodfwriter.cpp88
-rw-r--r--src/platformsupport/clipboard/qmacmime.mm19
-rw-r--r--src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h23
-rw-r--r--src/platformsupport/windowsuiautomation/uiatypes_p.h14
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp79
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp45
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h8
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp37
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.h5
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp27
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiawindowprovider.cpp168
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiawindowprovider.h73
-rw-r--r--src/plugins/platforms/windows/uiautomation/uiautomation.pri2
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp2
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp3
-rw-r--r--src/widgets/doc/snippets/cmake-macros/examples.cmake5
-rw-r--r--src/widgets/doc/src/cmake-macros.qdoc60
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp4
-rw-r--r--src/widgets/kernel/qwidget.cpp9
-rw-r--r--src/widgets/kernel/qwidget_p.h2
-rw-r--r--src/widgets/util/qcompleter.cpp40
-rw-r--r--src/widgets/widgets/qmenu.cpp11
-rw-r--r--src/widgets/widgets/qwidgetresizehandler.cpp2
-rw-r--r--src/winmain/qtmain_winrt.cpp9
-rw-r--r--src/xml/doc/src/qtxml-index.qdoc6
-rw-r--r--src/xml/doc/src/qtxml.qdoc6
34 files changed, 949 insertions, 237 deletions
diff --git a/src/corelib/doc/snippets/cmake-macros/examples.cmake b/src/corelib/doc/snippets/cmake-macros/examples.cmake
new file mode 100644
index 0000000000..bba082586f
--- /dev/null
+++ b/src/corelib/doc/snippets/cmake-macros/examples.cmake
@@ -0,0 +1,26 @@
+#! [qt5_wrap_cpp]
+set(SOURCES myapp.cpp main.cpp)
+qt5_wrap_cpp(SOURCES myapp.h)
+add_executable(myapp ${SOURCES})
+#! [qt5_wrap_cpp]
+
+#! [qt5_add_resources]
+set(SOURCES main.cpp)
+qt5_add_resources(SOURCES example.qrc)
+add_executable(myapp ${SOURCES})
+#! [qt5_add_resources]
+
+#! [qt5_add_big_resources]
+set(SOURCES main.cpp)
+qt5_add_big_resources(SOURCES big_resource.qrc)
+add_executable(myapp ${SOURCES})
+#! [qt5_add_big_resources]
+
+#! [qt5_add_binary_resources]
+qt5_add_binary_resources(resources project.qrc OPTIONS -no-compress)
+add_dependencies(myapp resources)
+#! [qt5_add_binary_resources]
+
+#! [qt5_generate_moc]
+qt5_generate_moc(main.cpp main.moc TARGET myapp)
+#! [qt5_generate_moc]
diff --git a/src/corelib/doc/src/cmake-macros.qdoc b/src/corelib/doc/src/cmake-macros.qdoc
new file mode 100644
index 0000000000..6140e8be44
--- /dev/null
+++ b/src/corelib/doc/src/cmake-macros.qdoc
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qtcore-cmake-qt5-wrap-cpp.html
+\ingroup cmake-macros-qtcore
+
+\title qt5_wrap_cpp
+
+\brief Creates \c{.moc} files from sources.
+
+\section1 Synopsis
+
+\badcode
+qt5_wrap_cpp(<VAR> src_file1 [src_file2 ...]
+ [TARGET target]
+ [OPTIONS ...]
+ [DEPENDS ...])
+\endcode
+
+\section1 Description
+
+Creates rules for calling \l{moc}{Meta-Object Compiler (moc)} on the given
+source files. For each input file, an output file is generated in the build
+directory. The paths of the generated files are added to\c{<VAR>}.
+
+\note This is a low-level macro. See the \l{CMake AUTOMOC Documentation} for a
+more convenient way to let source files be processed with \c{moc}.
+
+\section1 Options
+
+You can set an explicit \c{TARGET}. This will make sure that the target
+properties \c{INCLUDE_DIRECTORIES} and \c{COMPILE_DEFINITIONS} are also used
+when scanning the source files with \c{moc}.
+
+You can set additional \c{OPTIONS} that should be added to the \c{moc} calls.
+You can find possible options in the \l{moc}{moc documentation}.
+
+\c{DEPENDS} allows you to add additional dependencies for recreation of the
+generated files. This is useful when the sources have implicit dependencies,
+like code for a Qt plugin that includes a \c{.json} file using the
+Q_PLUGIN_METADATA() macro.
+
+\section1 Examples
+
+\snippet cmake-macros/examples.cmake qt5_wrap_cpp
+*/
+
+/*!
+\page qtcore-cmake-qt5-add-resources.html
+\ingroup cmake-macros-qtcore
+
+\title qt5_add_resources
+
+\brief Compiles binary resources into source code.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_resources(<VAR> file1.qrc [file2.qrc ...]
+ [OPTIONS ...])
+\endcode
+
+\section1 Description
+
+Creates source code from Qt resource files using the
+\l{Resource Compiler (rcc)}. Paths to the generated source files are added to
+\c{<VAR>}.
+
+\note This is a low-level macro. See the \l{CMake AUTORCC Documentation} for a
+more convenient way to let Qt resource files be processed with \c{rcc}.
+For embedding bigger resources, see \l qt5_add_big_resources.
+
+\section1 Arguments
+
+You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
+You can find possible options in the \l{rcc}{rcc documentation}.
+
+\section1 Examples
+
+\snippet cmake-macros/examples.cmake qt5_add_resources
+*/
+
+/*!
+\page qtcore-cmake-qt5-add-big-resources.html
+\ingroup cmake-macros-qtcore
+
+\title qt5_add_big_resources
+
+\brief Compiles big binary resources into object code.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_big_resources(<VAR> file1.qrc [file2.qrc ...]
+ [OPTIONS ...])
+\endcode
+
+\section1 Description
+
+Creates compiled object files from Qt resource files using the
+\l{Resource Compiler (rcc)}. Paths to the generated files are added to
+\c{<VAR>}.
+
+This is similar to \l qt5_add_resources, but directly generates object
+files (\c .o, \c .obj) files instead of C++ source code. This allows to
+embed bigger resources, where compiling to C++ sources and then to
+binaries would be too time consuming or memory intensive.
+
+\section1 Arguments
+
+You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
+You can find possible options in the \l{rcc}{rcc documentation}.
+
+\section1 Examples
+
+\snippet cmake-macros/examples.cmake qt5_add_big_resources
+*/
+
+/*!
+\page qtcore-cmake-qt5_add_binary_resources.html
+\ingroup cmake-macros-qtcore
+
+\title qt5_add_binary_resources
+
+\brief Creates an \c{RCC} file from a list of Qt resource files.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_binary_resources(target file1.qrc [file2.qrc ...]
+ [DESTINATION ...]
+ [OPTIONS ...])
+\endcode
+
+\section1 Description
+
+Adds a custom \c target that compiles Qt resource files into a binary \c{.rcc}
+file.
+
+\section1 Arguments
+
+\c{DESTINATION} sets the path of the generated \c{.rcc} file. The default is
+\c{${CMAKE_CURRENT_BINARY_DIR}/${target}.rcc}.
+
+You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
+You can find possible options in the \l{rcc}{rcc documentation}.
+
+\section1 Examples
+
+\snippet cmake-macros/examples.cmake qt5_add_binary_resources
+*/
+
+/*!
+\page qtcore-cmake-qt5-generate-moc.html
+\ingroup cmake-macros-qtcore
+
+\title qt5_generate_moc
+
+\brief Calls moc on an input file.
+
+\section1 Synopsis
+
+\badcode
+qt5_generate_moc(src_file dest_file
+ [TARGET target])
+\endcode
+
+\section1 Description
+
+Creates a rule to call the \l{moc}{Meta-Object Compiler (moc)} on \c src_file
+and store the output in \c dest_file.
+
+\note This is a low-level macro. See the \l{CMake AUTOMOC Documentation} for a
+more convenient way to let source files be processed with \c{moc}.
+\l qt5_wrap_cpp is also similar, but automatically generates a temporary file
+path for you.
+
+\section1 Arguments
+
+You can set an explicit \c{TARGET}. This will make sure that the target
+properties \c{INCLUDE_DIRECTORIES} and \c{COMPILE_DEFINITIONS} are also used
+when scanning the source files with \c{moc}.
+
+\section1 Examples
+
+\snippet cmake-macros/examples.cmake qt5_generate_moc
+*/
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index 51ace3d5f7..1efb49017f 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -230,7 +230,8 @@ public:
template<typename T> static QMetaEnum fromType() {
Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value,
- "QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG");
+ "QMetaEnum::fromType only works with enums declared as "
+ "Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS");
const QMetaObject *metaObject = qt_getEnumMetaObject(T());
const char *name = qt_getEnumName(T());
return metaObject->enumerator(metaObject->indexOfEnumerator(name));
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 4b85973e92..4f8e9a3817 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -492,5 +492,13 @@ QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
return platformScreen->geometry().topLeft();
}
+QPoint QHighDpiScaling::origin(const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return window->screen()->geometry().topLeft();
+
+ return QPoint(0, 0);
+}
+
#endif //QT_NO_HIGHDPISCALING
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index 28cf7de75b..dfc6abf5ba 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -83,6 +83,7 @@ public:
static qreal factor(const QPlatformScreen *platformScreen);
static QPoint origin(const QScreen *screen);
static QPoint origin(const QPlatformScreen *platformScreen);
+ static QPoint origin(const QWindow *window);
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
@@ -203,94 +204,42 @@ inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window)
return pos * scaleFactor;
}
-inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen)
+template <typename C>
+inline QRect fromNativePixels(const QRect &pixelRect, const C *context)
{
- const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
- const QPoint origin = QHighDpiScaling::origin(platformScreen);
+ const qreal scaleFactor = QHighDpiScaling::factor(context);
+ const QPoint origin = QHighDpiScaling::origin(context);
return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
fromNative(pixelRect.size(), scaleFactor));
}
-inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen)
+template <typename C>
+inline QRect toNativePixels(const QRect &pointRect, const C *context)
{
- const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
- const QPoint origin = QHighDpiScaling::origin(platformScreen);
+ const qreal scaleFactor = QHighDpiScaling::factor(context);
+ const QPoint origin = QHighDpiScaling::origin(context);
return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
toNative(pointRect.size(), scaleFactor));
}
-inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen)
+template <typename C>
+inline QRectF toNativePixels(const QRectF &pointRect, const C *context)
{
- const qreal scaleFactor = QHighDpiScaling::factor(screen);
- const QPoint origin = QHighDpiScaling::origin(screen);
- return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
- fromNative(pixelRect.size(), scaleFactor));
-}
-
-inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen)
-{
- const qreal scaleFactor = QHighDpiScaling::factor(screen);
- const QPoint origin = QHighDpiScaling::origin(screen);
- return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
- toNative(pointRect.size(), scaleFactor));
-}
-
-inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window)
-{
- if (window && window->isTopLevel() && window->screen()) {
- return fromNativePixels(pixelRect, window->screen());
- } else {
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor));
- }
-}
-
-inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen)
-{
- const qreal scaleFactor = QHighDpiScaling::factor(screen);
- const QPoint origin = QHighDpiScaling::origin(screen);
+ const qreal scaleFactor = QHighDpiScaling::factor(context);
+ const QPoint origin = QHighDpiScaling::origin(context);
return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin),
- toNative(pointRect.size(), scaleFactor));
+ toNative(pointRect.size(), scaleFactor));
}
-inline QRect toNativePixels(const QRect &pointRect, const QWindow *window)
+template <typename C>
+inline QRectF fromNativePixels(const QRectF &pixelRect, const C *context)
{
- if (window && window->isTopLevel() && window->screen()) {
- return toNativePixels(pointRect, window->screen());
- } else {
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor));
- }
-}
-
-inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen)
-{
- const qreal scaleFactor = QHighDpiScaling::factor(screen);
- const QPoint origin = QHighDpiScaling::origin(screen);
+ const qreal scaleFactor = QHighDpiScaling::factor(context);
+ const QPoint origin = QHighDpiScaling::origin(context);
return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin),
fromNative(pixelRect.size(), scaleFactor));
}
-inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window)
-{
- if (window && window->isTopLevel() && window->screen()) {
- return fromNativePixels(pixelRect, window->screen());
- } else {
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor);
- }
-}
-
-inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window)
-{
- if (window && window->isTopLevel() && window->screen()) {
- return toNativePixels(pointRect, window->screen());
- } else {
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor);
- }
-}
-
inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window)
{
return pixelSize / QHighDpiScaling::factor(window);
@@ -311,56 +260,28 @@ inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window)
return pointSize * QHighDpiScaling::factor(window);
}
-inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen)
+template <typename C>
+inline QPoint fromNativePixels(const QPoint &pixelPoint, const C *context)
{
- return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+ return fromNative(pixelPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
-inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window)
+template <typename C>
+inline QPoint toNativePixels(const QPoint &pointPoint, const C *context)
{
- if (window && window->isTopLevel() && window->screen())
- return fromNativePixels(pixelPoint, window->screen());
- else
- return pixelPoint / QHighDpiScaling::factor(window);
+ return toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
-inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen)
+template <typename C>
+inline QPointF fromNativePixels(const QPointF &pixelPoint, const C *context)
{
- return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+ return fromNative(pixelPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
-inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window)
+template <typename C>
+inline QPointF toNativePixels(const QPointF &pointPoint, const C *context)
{
- if (window && window->isTopLevel() && window->screen())
- return toNativePixels(pointPoint, window->screen());
- else
- return pointPoint * QHighDpiScaling::factor(window);
-}
-
-inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen)
-{
- return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
-}
-
-inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window)
-{
- if (window && window->isTopLevel() && window->screen())
- return fromNativePixels(pixelPoint, window->screen());
- else
- return pixelPoint / QHighDpiScaling::factor(window);
-}
-
-inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen)
-{
- return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
-}
-
-inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window)
-{
- if (window && window->isTopLevel() && window->screen())
- return toNativePixels(pointPoint, window->screen());
- else
- return pointPoint * QHighDpiScaling::factor(window);
+ return toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window)
@@ -425,47 +346,26 @@ inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *wi
}
// Any T that has operator/()
-template <typename T>
-T fromNativePixels(const T &pixelValue, const QWindow *window)
-{
- if (!QHighDpiScaling::isActive())
- return pixelValue;
-
- return pixelValue / QHighDpiScaling::factor(window);
-
-}
-
- //##### ?????
-template <typename T>
-T fromNativePixels(const T &pixelValue, const QScreen *screen)
+template <typename T, typename C>
+T fromNativePixels(const T &pixelValue, const C *context)
{
if (!QHighDpiScaling::isActive())
return pixelValue;
- return pixelValue / QHighDpiScaling::factor(screen);
+ return pixelValue / QHighDpiScaling::factor(context);
}
// Any T that has operator*()
-template <typename T>
-T toNativePixels(const T &pointValue, const QWindow *window)
-{
- if (!QHighDpiScaling::isActive())
- return pointValue;
-
- return pointValue * QHighDpiScaling::factor(window);
-}
-
-template <typename T>
-T toNativePixels(const T &pointValue, const QScreen *screen)
+template <typename T, typename C>
+T toNativePixels(const T &pointValue, const C *context)
{
if (!QHighDpiScaling::isActive())
return pointValue;
- return pointValue * QHighDpiScaling::factor(screen);
+ return pointValue * QHighDpiScaling::factor(context);
}
-
// Any QVector<T> where T has operator/()
template <typename T>
QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window)
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 562289a8c9..4e95751397 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -705,14 +705,20 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
w, defaultWidth, defaultHeight);
return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor));
}
- const QScreen *screen = effectiveScreen(w);
+ const auto *wp = qt_window_private(const_cast<QWindow*>(w));
+ const bool position = wp->positionAutomatic && w->type() != Qt::Popup;
+ if (!position && !wp->resizeAutomatic)
+ return initialGeometry;
+ const QScreen *screen = wp->positionAutomatic
+ ? effectiveScreen(w)
+ : QGuiApplication::screenAt(initialGeometry.center());
if (!screen)
return initialGeometry;
- const auto *wp = qt_window_private(const_cast<QWindow*>(w));
+ // initialGeometry refers to window's screen
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
if (wp->resizeAutomatic)
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
- if (wp->positionAutomatic && w->type() != Qt::Popup) {
+ if (position) {
const QRect availableGeometry = screen->availableGeometry();
// Center unless the geometry ( + unknown window frame) is too large for the screen).
if (rect.height() < (availableGeometry.height() * 8) / 9
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index a62e7e425a..9721243454 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -43,6 +43,7 @@
#include "qtextodfwriter_p.h"
+#include <QImageReader>
#include <QImageWriter>
#include <QTextListFormat>
#include <QTextList>
@@ -410,6 +411,29 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
writer.writeEndElement(); // list-item
}
+static bool probeImageData(QIODevice *device, QImage *image, QString *mimeType, qreal *width, qreal *height)
+{
+ QImageReader reader(device);
+ const QByteArray format = reader.format().toLower();
+ if (format == "png") {
+ *mimeType = QStringLiteral("image/png");
+ } else if (format == "jpg") {
+ *mimeType = QStringLiteral("image/jpg");
+ } else if (format == "svg") {
+ *mimeType = QStringLiteral("image/svg+xml");
+ } else {
+ *image = reader.read();
+ return false;
+ }
+
+ const QSize size = reader.size();
+
+ *width = size.width();
+ *height = size.height();
+
+ return true;
+}
+
void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextFragment &fragment) const
{
writer.writeStartElement(drawNS, QString::fromLatin1("frame"));
@@ -420,47 +444,73 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
QTextImageFormat imageFormat = fragment.charFormat().toImageFormat();
writer.writeAttribute(drawNS, QString::fromLatin1("name"), imageFormat.name());
+ QByteArray data;
+ QString mimeType;
+ qreal width = 0;
+ qreal height = 0;
+
QImage image;
QString name = imageFormat.name();
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
name.prepend(QLatin1String("qrc"));
QUrl url = QUrl(name);
- const QVariant data = m_document->resource(QTextDocument::ImageResource, url);
- if (data.type() == QVariant::Image) {
- image = qvariant_cast<QImage>(data);
- } else if (data.type() == QVariant::ByteArray) {
- image.loadFromData(data.toByteArray());
- }
-
- if (image.isNull()) {
- if (image.isNull()) { // try direct loading
- name = imageFormat.name(); // remove qrc:/ prefix again
- image.load(name);
+ const QVariant variant = m_document->resource(QTextDocument::ImageResource, url);
+ if (variant.type() == QVariant::Image) {
+ image = qvariant_cast<QImage>(variant);
+ } else if (variant.type() == QVariant::ByteArray) {
+ data = variant.toByteArray();
+
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+ probeImageData(&buffer, &image, &mimeType, &width, &height);
+ } else {
+ // try direct loading
+ QFile file(imageFormat.name());
+ if (file.open(QIODevice::ReadOnly) && !probeImageData(&file, &image, &mimeType, &width, &height)) {
+ file.seek(0);
+ data = file.readAll();
}
}
if (! image.isNull()) {
QBuffer imageBytes;
- QString filename = m_strategy->createUniqueImageName();
+
int imgQuality = imageFormat.quality();
if (imgQuality >= 100 || imgQuality < 0 || image.hasAlphaChannel()) {
QImageWriter imageWriter(&imageBytes, "png");
imageWriter.write(image);
- m_strategy->addFile(filename, QString::fromLatin1("image/png"), imageBytes.data());
+
+ data = imageBytes.data();
+ mimeType = QStringLiteral("image/png");
} else {
// Write images without alpha channel as jpg with quality set by QTextImageFormat
QImageWriter imageWriter(&imageBytes, "jpg");
imageWriter.setQuality(imgQuality);
imageWriter.write(image);
- m_strategy->addFile(filename, QString::fromLatin1("image/jpg"), imageBytes.data());
+
+ data = imageBytes.data();
+ mimeType = QStringLiteral("image/jpg");
}
- // get the width/height from the format.
- qreal width = imageFormat.hasProperty(QTextFormat::ImageWidth)
- ? imageFormat.width() : image.width();
+
+ width = image.width();
+ height = image.height();
+ }
+
+ if (!data.isEmpty()) {
+ if (imageFormat.hasProperty(QTextFormat::ImageWidth)) {
+ width = imageFormat.width();
+ }
+ if (imageFormat.hasProperty(QTextFormat::ImageHeight)) {
+ height = imageFormat.height();
+ }
+
+ QString filename = m_strategy->createUniqueImageName();
+
+ m_strategy->addFile(filename, mimeType, data);
+
writer.writeAttribute(svgNS, QString::fromLatin1("width"), pixelToPoint(width));
- qreal height = imageFormat.hasProperty(QTextFormat::ImageHeight)
- ? imageFormat.height() : image.height();
writer.writeAttribute(svgNS, QString::fromLatin1("height"), pixelToPoint(height));
+ writer.writeAttribute(textNS, QStringLiteral("anchor-type"), QStringLiteral("as-char"));
writer.writeStartElement(drawNS, QString::fromLatin1("image"));
writer.writeAttribute(xlinkNS, QString::fromLatin1("href"), filename);
writer.writeEndElement(); // image
diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm
index f425e34b39..76e9c8712c 100644
--- a/src/platformsupport/clipboard/qmacmime.mm
+++ b/src/platformsupport/clipboard/qmacmime.mm
@@ -435,8 +435,23 @@ QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &
if (flavor == QLatin1String("public.utf8-plain-text"))
ret.append(string.toUtf8());
#if QT_CONFIG(textcodec)
- else if (flavor == QLatin1String("public.utf16-plain-text"))
- ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(string));
+ else if (flavor == QLatin1String("public.utf16-plain-text")) {
+ QTextCodec::ConverterState state;
+#if defined(Q_OS_MACOS)
+ // Some applications such as Microsoft Excel, don't deal well with
+ // a BOM present, so we follow the traditional approach of Qt on
+ // macOS to not generate public.utf16-plain-text with a BOM.
+ state.flags = QTextCodec::IgnoreHeader;
+#else
+ // Whereas iOS applications will fail to paste if we do _not_
+ // include a BOM in the public.utf16-plain-text content, most
+ // likely due to converting the data using NSUTF16StringEncoding
+ // which assumes big-endian byte order if there is no BOM.
+ state.flags = QTextCodec::DefaultConversion;
+#endif
+ ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(
+ string.constData(), string.length(), &state));
+ }
#endif
return ret;
}
diff --git a/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h b/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
index 64c54c694a..fd39b6ee33 100644
--- a/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
+++ b/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
@@ -360,4 +360,27 @@ __CRT_UUID_DECL(IGridItemProvider, 0xd02541f1, 0xfb81, 0x4d64, 0xae,0x32, 0xf5,0
#endif
#endif
+
+#ifndef __IWindowProvider_INTERFACE_DEFINED__
+#define __IWindowProvider_INTERFACE_DEFINED__
+DEFINE_GUID(IID_IWindowProvider, 0x987df77b, 0xdb06, 0x4d77, 0x8f,0x8a, 0x86,0xa9,0xc3,0xbb,0x90,0xb9);
+MIDL_INTERFACE("987df77b-db06-4d77-8f8a-86a9c3bb90b9")
+IWindowProvider : public IUnknown
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE SetVisualState(enum WindowVisualState state) = 0;
+ virtual HRESULT STDMETHODCALLTYPE Close( void) = 0;
+ virtual HRESULT STDMETHODCALLTYPE WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) = 0;
+ virtual HRESULT STDMETHODCALLTYPE get_CanMaximize(__RPC__out BOOL *pRetVal) = 0;
+ virtual HRESULT STDMETHODCALLTYPE get_CanMinimize(__RPC__out BOOL *pRetVal) = 0;
+ virtual HRESULT STDMETHODCALLTYPE get_IsModal(__RPC__out BOOL *pRetVal) = 0;
+ virtual HRESULT STDMETHODCALLTYPE get_WindowVisualState(__RPC__out enum WindowVisualState *pRetVal) = 0;
+ virtual HRESULT STDMETHODCALLTYPE get_WindowInteractionState(__RPC__out enum WindowInteractionState *pRetVal) = 0;
+ virtual HRESULT STDMETHODCALLTYPE get_IsTopmost(__RPC__out BOOL *pRetVal) = 0;
+};
+#ifdef __CRT_UUID_DECL
+__CRT_UUID_DECL(IWindowProvider, 0x987df77b, 0xdb06, 0x4d77, 0x8f,0x8a, 0x86,0xa9,0xc3,0xbb,0x90,0xb9)
+#endif
+#endif
+
#endif
diff --git a/src/platformsupport/windowsuiautomation/uiatypes_p.h b/src/platformsupport/windowsuiautomation/uiatypes_p.h
index ea58417943..8ef71843a3 100644
--- a/src/platformsupport/windowsuiautomation/uiatypes_p.h
+++ b/src/platformsupport/windowsuiautomation/uiatypes_p.h
@@ -141,6 +141,20 @@ enum PropertyConditionFlags {
PropertyConditionFlags_IgnoreCase = 1
};
+enum WindowVisualState {
+ WindowVisualState_Normal = 0,
+ WindowVisualState_Maximized = 1,
+ WindowVisualState_Minimized = 2
+};
+
+enum WindowInteractionState {
+ WindowInteractionState_Running = 0,
+ WindowInteractionState_Closing = 1,
+ WindowInteractionState_ReadyForUserInteraction = 2,
+ WindowInteractionState_BlockedByModalWindow = 3,
+ WindowInteractionState_NotResponding = 4
+};
+
struct UiaRect {
double left;
double top;
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 07a6b52dbe..db40c30d7d 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -1129,46 +1129,63 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/)
QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
{
- //### the preedit text could theoretically be after the cursor
- QVariant textAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, QVariant(length));
- if (textAfter.isValid()) {
- return textAfter.toString().left(length);
- }
-
- //compatibility code for old controls that do not implement the new API
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
- if (query.isNull())
+ if (length <= 0)
return QString();
- QString text = query->value(Qt::ImSurroundingText).toString();
- if (!text.length())
- return text;
+ QString text;
- int cursorPos = query->value(Qt::ImCursorPosition).toInt();
- return text.mid(cursorPos, length);
+ QVariant reportedTextAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, length);
+ if (reportedTextAfter.isValid()) {
+ text = reportedTextAfter.toString();
+ } else {
+ // Compatibility code for old controls that do not implement the new API
+ QSharedPointer<QInputMethodQueryEvent> query =
+ focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImSurroundingText);
+ if (query) {
+ const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ text = query->value(Qt::ImSurroundingText).toString().mid(cursorPos);
+ }
+ }
+
+ // Controls do not report preedit text, so we have to add it
+ if (!m_composingText.isEmpty()) {
+ const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
+ text = m_composingText.midRef(cursorPosInsidePreedit) + text;
+ }
+
+ text.truncate(length);
+ return text;
}
QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
{
- QVariant textBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, QVariant(length));
- if (textBefore.isValid())
- return textBefore.toString().rightRef(length) + m_composingText;
-
- //compatibility code for old controls that do not implement the new API
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
- if (query.isNull())
+ if (length <= 0)
return QString();
- int cursorPos = query->value(Qt::ImCursorPosition).toInt();
- QString text = query->value(Qt::ImSurroundingText).toString();
- if (!text.length())
- return text;
+ QString text;
- //### the preedit text does not need to be immediately before the cursor
- if (cursorPos <= length)
- return text.leftRef(cursorPos) + m_composingText;
- else
- return text.midRef(cursorPos - length, length) + m_composingText;
+ QVariant reportedTextBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, length);
+ if (reportedTextBefore.isValid()) {
+ text = reportedTextBefore.toString();
+ } else {
+ // Compatibility code for old controls that do not implement the new API
+ QSharedPointer<QInputMethodQueryEvent> query =
+ focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImSurroundingText);
+ if (query) {
+ const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ text = query->value(Qt::ImSurroundingText).toString().left(cursorPos);
+ }
+ }
+
+ // Controls do not report preedit text, so we have to add it
+ if (!m_composingText.isEmpty()) {
+ const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
+ text += m_composingText.leftRef(cursorPosInsidePreedit);
+ }
+
+ if (text.length() > length)
+ text = text.right(length);
+ return text;
}
/*
@@ -1231,6 +1248,8 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
if (query.isNull())
return JNI_FALSE;
+ if (start == end)
+ return JNI_TRUE;
if (start > end)
qSwap(start, end);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp
index 738c30c65a..b8f04cf978 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp
@@ -221,7 +221,7 @@ EGLNativeWindowType QEglFSOpenWFDIntegration::createNativeWindow(QPlatformWindow
QSurfaceFormat QEglFSOpenWFDIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
{
- QSurfaceFormat format;
+ QSurfaceFormat format = inputFormat;
format.setRedBufferSize(8);
format.setGreenBufferSize(8);
format.setBlueBufferSize(8);
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 281f18af5b..55e7e32979 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -1488,6 +1488,10 @@ void QWindowsContext::handleExitSizeMove(QWindow *window)
keyboardModifiers);
}
}
+ if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer)
+ d->m_pointerHandler.clearEvents();
+ else
+ d->m_mouseHandler.clearEvents();
}
bool QWindowsContext::asyncExpose() const
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 737fd1d2a9..e33591c33d 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -157,6 +157,12 @@ QTouchDevice *QWindowsMouseHandler::ensureTouchDevice()
return m_touchDevice;
}
+void QWindowsMouseHandler::clearEvents()
+{
+ m_lastEventType = QEvent::None;
+ m_lastEventButton = Qt::NoButton;
+}
+
Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
{
Qt::MouseButtons result = nullptr;
@@ -287,8 +293,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
- const MouseEvent mouseEvent = eventFromMsg(msg);
-
// Check for events synthesized from touch. Lower byte is touch index, 0 means pen.
static const bool passSynthesizedMouseEvents =
!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch);
@@ -305,13 +309,40 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
}
+ const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
+ const MouseEvent mouseEvent = eventFromMsg(msg);
+ Qt::MouseButtons buttons;
+
+ if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick)
+ buttons = queryMouseButtons();
+ else
+ buttons = keyStateToMouseButtons(msg.wParam);
+
+ // When the left/right mouse buttons are pressed over the window title bar
+ // WM_NCLBUTTONDOWN/WM_NCRBUTTONDOWN messages are received. But no UP
+ // messages are received on release, only WM_NCMOUSEMOVE/WM_MOUSEMOVE.
+ // We detect it and generate the missing release events here. (QTBUG-75678)
+ // The last event vars are cleared on QWindowsContext::handleExitSizeMove()
+ // to avoid generating duplicated release events.
+ if (m_lastEventType == QEvent::NonClientAreaMouseButtonPress
+ && (mouseEvent.type == QEvent::NonClientAreaMouseMove || mouseEvent.type == QEvent::MouseMove)
+ && (m_lastEventButton & buttons) == 0) {
+ if (mouseEvent.type == QEvent::NonClientAreaMouseMove) {
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition, globalPosition, buttons, m_lastEventButton,
+ QEvent::NonClientAreaMouseButtonRelease, keyModifiers, source);
+ } else {
+ QWindowSystemInterface::handleMouseEvent(window, clientPosition, globalPosition, buttons, m_lastEventButton,
+ QEvent::MouseButtonRelease, keyModifiers, source);
+ }
+ }
+ m_lastEventType = mouseEvent.type;
+ m_lastEventButton = mouseEvent.button;
+
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
- const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
globalPosition, buttons,
mouseEvent.button, mouseEvent.type,
- QWindowsKeyMapper::queryKeyboardModifiers(),
- source);
+ keyModifiers, source);
return false; // Allow further event processing (dragging of windows).
}
@@ -334,7 +365,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
- const Qt::MouseButtons buttons = keyStateToMouseButtons(int(msg.wParam));
// If the window was recently resized via mouse doubleclick on the frame or title bar,
// we don't get WM_LBUTTONDOWN or WM_LBUTTONDBLCLK for the second click,
@@ -461,8 +491,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
if (!discardEvent && mouseEvent.type != QEvent::None) {
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
mouseEvent.button, mouseEvent.type,
- QWindowsKeyMapper::queryKeyboardModifiers(),
- source);
+ keyModifiers, source);
}
m_previousCaptureWindow = hasCapture ? window : nullptr;
// QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
index 480662c9bf..5fe4b09c1e 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.h
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -45,6 +45,7 @@
#include <QtCore/qpointer.h>
#include <QtCore/qhash.h>
+#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE
@@ -72,13 +73,14 @@ public:
bool translateScrollEvent(QWindow *window, HWND hwnd,
MSG msg, LRESULT *result);
- static inline Qt::MouseButtons keyStateToMouseButtons(int);
+ static inline Qt::MouseButtons keyStateToMouseButtons(WPARAM);
static inline Qt::KeyboardModifiers keyStateToModifiers(int);
static inline int mouseButtonsToKeyState(Qt::MouseButtons);
static Qt::MouseButtons queryMouseButtons();
QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); }
void clearWindowUnderMouse() { m_windowUnderMouse = 0; }
+ void clearEvents();
private:
inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd,
@@ -91,9 +93,11 @@ private:
QTouchDevice *m_touchDevice = nullptr;
bool m_leftButtonDown = false;
QWindow *m_previousCaptureWindow = nullptr;
+ QEvent::Type m_lastEventType = QEvent::None;
+ Qt::MouseButton m_lastEventButton = Qt::NoButton;
};
-Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam)
+Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(WPARAM wParam)
{
Qt::MouseButtons mb(Qt::NoButton);
if (wParam & MK_LBUTTON)
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index 501b62e07a..fd3d711470 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -336,6 +336,12 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice()
return m_touchDevice;
}
+void QWindowsPointerHandler::clearEvents()
+{
+ m_lastEventType = QEvent::None;
+ m_lastEventButton = Qt::NoButton;
+}
+
void QWindowsPointerHandler::handleCaptureRelease(QWindow *window,
QWindow *currentWindowUnderPointer,
HWND hwnd,
@@ -726,10 +732,35 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
}
const MouseEvent mouseEvent = eventFromMsg(msg);
+ Qt::MouseButtons mouseButtons;
+
+ if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick)
+ mouseButtons = queryMouseButtons();
+ else
+ mouseButtons = mouseButtonsFromKeyState(msg.wParam);
+
+ // When the left/right mouse buttons are pressed over the window title bar
+ // WM_NCLBUTTONDOWN/WM_NCRBUTTONDOWN messages are received. But no UP
+ // messages are received on release, only WM_NCMOUSEMOVE/WM_MOUSEMOVE.
+ // We detect it and generate the missing release events here. (QTBUG-75678)
+ // The last event vars are cleared on QWindowsContext::handleExitSizeMove()
+ // to avoid generating duplicated release events.
+ if (m_lastEventType == QEvent::NonClientAreaMouseButtonPress
+ && (mouseEvent.type == QEvent::NonClientAreaMouseMove || mouseEvent.type == QEvent::MouseMove)
+ && (m_lastEventButton & mouseButtons) == 0) {
+ if (mouseEvent.type == QEvent::NonClientAreaMouseMove) {
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, m_lastEventButton,
+ QEvent::NonClientAreaMouseButtonRelease, keyModifiers, source);
+ } else {
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, m_lastEventButton,
+ QEvent::MouseButtonRelease, keyModifiers, source);
+ }
+ }
+ m_lastEventType = mouseEvent.type;
+ m_lastEventButton = mouseEvent.button;
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
- const Qt::MouseButtons nonclientButtons = queryMouseButtons();
- QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, nonclientButtons,
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
mouseEvent.button, mouseEvent.type, keyModifiers, source);
return false; // Allow further event processing
}
@@ -745,8 +776,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
return true;
}
- const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
-
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h
index aebef062bc..ccbb1d3939 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.h
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.h
@@ -46,7 +46,7 @@
#include <QtCore/qpointer.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qhash.h>
-#include <qpa/qwindowsysteminterface.h>
+#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE
@@ -64,6 +64,7 @@ public:
QTouchDevice *ensureTouchDevice();
QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); }
void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; }
+ void clearEvents();
private:
bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count);
@@ -79,6 +80,8 @@ private:
QPointer<QWindow> m_currentWindow;
QWindow *m_previousCaptureWindow = nullptr;
bool m_needsEnterOnPointerUpdate = false;
+ QEvent::Type m_lastEventType = QEvent::None;
+ Qt::MouseButton m_lastEventButton = Qt::NoButton;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 44328492a6..a427e553f0 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -52,6 +52,7 @@
#include "qwindowsuiatableitemprovider.h"
#include "qwindowsuiagridprovider.h"
#include "qwindowsuiagriditemprovider.h"
+#include "qwindowsuiawindowprovider.h"
#include "qwindowscombase.h"
#include "qwindowscontext.h"
#include "qwindowsuiautils.h"
@@ -263,6 +264,11 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow
return UIA_E_ELEMENTNOTAVAILABLE;
switch (idPattern) {
+ case UIA_WindowPatternId:
+ if (accessible->parent() && (accessible->parent()->role() == QAccessible::Application)) {
+ *pRetVal = new QWindowsUiaWindowProvider(id());
+ }
+ break;
case UIA_TextPatternId:
case UIA_TextPattern2Id:
// All text controls.
@@ -352,8 +358,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
if (!accessible)
return UIA_E_ELEMENTNOTAVAILABLE;
- bool clientTopLevel = (accessible->role() == QAccessible::Client)
- && accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
+ bool topLevelWindow = accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
switch (idProp) {
case UIA_ProcessIdPropertyId:
@@ -379,7 +384,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
setVariantString(QStringLiteral("Qt"), pRetVal);
break;
case UIA_ControlTypePropertyId:
- if (clientTopLevel) {
+ if (topLevelWindow) {
// Reports a top-level widget as a window, instead of "custom".
setVariantI4(UIA_WindowControlTypeId, pRetVal);
} else {
@@ -391,10 +396,20 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
setVariantString(accessible->text(QAccessible::Help), pRetVal);
break;
case UIA_HasKeyboardFocusPropertyId:
- setVariantBool(accessible->state().focused, pRetVal);
+ if (topLevelWindow) {
+ // Windows set the active state to true when they are focused
+ setVariantBool(accessible->state().active, pRetVal);
+ } else {
+ setVariantBool(accessible->state().focused, pRetVal);
+ }
break;
case UIA_IsKeyboardFocusablePropertyId:
- setVariantBool(accessible->state().focusable, pRetVal);
+ if (topLevelWindow) {
+ // Windows should always be focusable
+ setVariantBool(true, pRetVal);
+ } else {
+ setVariantBool(accessible->state().focusable, pRetVal);
+ }
break;
case UIA_IsOffscreenPropertyId:
setVariantBool(accessible->state().offscreen, pRetVal);
@@ -424,7 +439,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
break;
case UIA_NamePropertyId: {
QString name = accessible->text(QAccessible::Name);
- if (name.isEmpty() && clientTopLevel)
+ if (name.isEmpty() && topLevelWindow)
name = QCoreApplication::applicationName();
setVariantString(name, pRetVal);
break;
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiawindowprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiawindowprovider.cpp
new file mode 100644
index 0000000000..3738aa72ff
--- /dev/null
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiawindowprovider.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwindowsuiawindowprovider.h"
+#include "qwindowsuiautils.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/qaccessible.h>
+#include <QtGui/private/qwindow_p.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWindowsUiAutomation;
+
+
+QWindowsUiaWindowProvider::QWindowsUiaWindowProvider(QAccessible::Id id) :
+ QWindowsUiaBaseProvider(id)
+{
+}
+
+QWindowsUiaWindowProvider::~QWindowsUiaWindowProvider()
+{
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::SetVisualState(WindowVisualState state) {
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible || !accessible->window())
+ return UIA_E_ELEMENTNOTAVAILABLE;
+ auto window = accessible->window();
+ switch (state) {
+ case WindowVisualState_Normal:
+ window->showNormal();
+ break;
+ case WindowVisualState_Maximized:
+ window->showMaximized();
+ break;
+ case WindowVisualState_Minimized:
+ window->showMinimized();
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::Close() {
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible || !accessible->window())
+ return UIA_E_ELEMENTNOTAVAILABLE;
+ accessible->window()->close();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) {
+ Q_UNUSED(milliseconds);
+ Q_UNUSED(pRetVal);
+ return UIA_E_NOTSUPPORTED;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_CanMaximize(__RPC__out BOOL *pRetVal) {
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible || !accessible->window())
+ return UIA_E_ELEMENTNOTAVAILABLE;
+
+ auto window = accessible->window();
+ auto flags = window->flags();
+
+ *pRetVal = (!(flags & Qt::MSWindowsFixedSizeDialogHint)
+ && (flags & Qt::WindowMaximizeButtonHint)
+ && ((flags & Qt::CustomizeWindowHint)
+ || window->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_CanMinimize(__RPC__out BOOL *pRetVal) {
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible || !accessible->window())
+ return UIA_E_ELEMENTNOTAVAILABLE;
+ *pRetVal = accessible->window()->flags() & Qt::WindowMinimizeButtonHint;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_IsModal(__RPC__out BOOL *pRetVal) {
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible || !accessible->window())
+ return UIA_E_ELEMENTNOTAVAILABLE;
+ *pRetVal = accessible->window()->isModal();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_WindowVisualState(__RPC__out enum WindowVisualState *pRetVal) {
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible || !accessible->window())
+ return UIA_E_ELEMENTNOTAVAILABLE;
+ auto visibility = accessible->window()->visibility();
+ switch (visibility) {
+ case QWindow::FullScreen:
+ case QWindow::Maximized:
+ *pRetVal = WindowVisualState_Maximized;
+ break;
+ case QWindow::Minimized:
+ *pRetVal = WindowVisualState_Minimized;
+ break;
+ default:
+ *pRetVal = WindowVisualState_Normal;
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_WindowInteractionState(__RPC__out enum WindowInteractionState *pRetVal) {
+ Q_UNUSED(pRetVal);
+ return UIA_E_NOTSUPPORTED;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaWindowProvider::get_IsTopmost(__RPC__out BOOL *pRetVal) {
+ Q_UNUSED(pRetVal);
+ return UIA_E_NOTSUPPORTED;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiawindowprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiawindowprovider.h
new file mode 100644
index 0000000000..343fb275f7
--- /dev/null
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiawindowprovider.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSUIAWINDOWPROVIDER_H
+#define QWINDOWSUIAWINDOWPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwindowsuiabaseprovider.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsUiaWindowProvider : public QWindowsUiaBaseProvider,
+ public QWindowsComBase<IWindowProvider>
+{
+ Q_DISABLE_COPY(QWindowsUiaWindowProvider)
+public:
+ explicit QWindowsUiaWindowProvider(QAccessible::Id id);
+ ~QWindowsUiaWindowProvider() override;
+
+ HRESULT STDMETHODCALLTYPE SetVisualState(WindowVisualState state) override;
+ HRESULT STDMETHODCALLTYPE Close( void) override;
+ HRESULT STDMETHODCALLTYPE WaitForInputIdle(int milliseconds, __RPC__out BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_CanMaximize(__RPC__out BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_CanMinimize(__RPC__out BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_IsModal(__RPC__out BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_WindowVisualState(__RPC__out WindowVisualState *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_WindowInteractionState(__RPC__out WindowInteractionState *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_IsTopmost(__RPC__out BOOL *pRetVal) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINDOWSUIAWINDOWPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/uiautomation.pri b/src/plugins/platforms/windows/uiautomation/uiautomation.pri
index e3071766d9..5d4fa5755b 100644
--- a/src/plugins/platforms/windows/uiautomation/uiautomation.pri
+++ b/src/plugins/platforms/windows/uiautomation/uiautomation.pri
@@ -18,6 +18,7 @@ SOURCES += \
$$PWD/qwindowsuiatableitemprovider.cpp \
$$PWD/qwindowsuiagridprovider.cpp \
$$PWD/qwindowsuiagriditemprovider.cpp \
+ $$PWD/qwindowsuiawindowprovider.cpp \
$$PWD/qwindowsuiautils.cpp
HEADERS += \
@@ -37,6 +38,7 @@ HEADERS += \
$$PWD/qwindowsuiatableitemprovider.h \
$$PWD/qwindowsuiagridprovider.h \
$$PWD/qwindowsuiagriditemprovider.h \
+ $$PWD/qwindowsuiawindowprovider.h \
$$PWD/qwindowsuiautils.h
mingw: LIBS *= -luuid
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index aa329d8cb7..1ce947165d 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -202,7 +202,7 @@ void QXcbDrag::startDrag()
if (connection()->mouseGrabber() == nullptr)
shapedPixmapWindow()->setMouseGrabEnabled(true);
- auto nativePixelPos = QHighDpi::toNativePixels(QCursor::pos(), initiatorWindow);
+ auto nativePixelPos = QHighDpi::toNativePixels(QCursor::pos(), initiatorWindow.data());
move(nativePixelPos, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
}
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index c0bacd553d..8a1bd1431e 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -1859,6 +1859,9 @@ void QColorDialogPrivate::_q_addCustom()
void QColorDialogPrivate::retranslateStrings()
{
+ if (nativeDialogInUse)
+ return;
+
if (!smallDisplay) {
lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
lblCustomColors->setText(QColorDialog::tr("&Custom colors"));
diff --git a/src/widgets/doc/snippets/cmake-macros/examples.cmake b/src/widgets/doc/snippets/cmake-macros/examples.cmake
new file mode 100644
index 0000000000..61ec7aed54
--- /dev/null
+++ b/src/widgets/doc/snippets/cmake-macros/examples.cmake
@@ -0,0 +1,5 @@
+#! [qt5_wrap_ui]
+set(SOURCES mainwindow.cpp main.cpp)
+qt5_wrap_ui(SOURCES mainwindow.ui)
+add_executable(myapp ${SOURCES})
+#! [qt5_wrap_ui]
diff --git a/src/widgets/doc/src/cmake-macros.qdoc b/src/widgets/doc/src/cmake-macros.qdoc
new file mode 100644
index 0000000000..36579576a9
--- /dev/null
+++ b/src/widgets/doc/src/cmake-macros.qdoc
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qtwidgets-cmake-qt5-wrap-ui.html
+\ingroup cmake-macros-qtwidgets
+
+\title qt5_wrap_ui
+
+\brief Creates sources for \c{.ui} files.
+
+\section1 Synopsis
+
+\badcode
+qt5_wrap_ui(<VAR> ui_file1 [ui_file2 ...]
+ [OPTIONS ...])
+\endcode
+
+\section1 Description
+
+Creates rules for calling \l{uic}{User Interface Compiler (uic)} on the given
+\c{.ui} files. For each input file, an header file is generated in the build
+directory. The paths of the generated header files are added to\c{<VAR>}.
+
+\note This is a low-level macro. See the \l{CMake AUTOUIC Documentation} for a
+more convenient way to process \c{.ui} files with \c{uic}.
+
+\section1 Options
+
+You can set additional \c{OPTIONS} that should be added to the \c{uic} calls.
+You can find possible options in the \l{uic}{uic documentation}.
+
+\section1 Examples
+
+\snippet cmake-macros/examples.cmake qt5_wrap_ui
+*/
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 713f022bdd..65708fa1ca 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -9795,9 +9795,9 @@ QRectF QGraphicsPixmapItem::boundingRect() const
return QRectF();
if (d->flags & ItemIsSelectable) {
qreal pw = 1.0;
- return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
+ return QRectF(d->offset, QSizeF(d->pixmap.size()) / d->pixmap.devicePixelRatio()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
} else {
- return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio());
+ return QRectF(d->offset, QSizeF(d->pixmap.size()) / d->pixmap.devicePixelRatio());
}
}
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index d863ef625b..0682717f54 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -2583,14 +2583,15 @@ void QWidgetPrivate::createWinId()
/*!
\internal
Ensures that the widget is set on the screen point is on. This is handy getting a correct
-size hint before a resize in e.g QMenu and QToolTip
+size hint before a resize in e.g QMenu and QToolTip.
+Returns if the screen was changed.
*/
-void QWidgetPrivate::setScreenForPoint(const QPoint &pos)
+bool QWidgetPrivate::setScreenForPoint(const QPoint &pos)
{
Q_Q(QWidget);
if (!q->isWindow())
- return;
+ return false;
// Find the screen for pos and make the widget undertand it is on that screen.
const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
QScreen *actualScreen = QGuiApplication::screenAt(pos);
@@ -2599,7 +2600,9 @@ void QWidgetPrivate::setScreenForPoint(const QPoint &pos)
createWinId();
if (windowHandle())
windowHandle()->setScreen(actualScreen);
+ return true;
}
+ return false;
}
/*!
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 797963b931..af4ad31501 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -355,7 +355,7 @@ public:
void createRecursively();
void createWinId();
- void setScreenForPoint(const QPoint &pos);
+ bool setScreenForPoint(const QPoint &pos);
void createTLExtra();
void createExtra();
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 0daa4a4b41..e41f7e7573 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -976,18 +976,48 @@ void QCompleterPrivate::showPopup(const QRect& rect)
popup->show();
}
+#if QT_CONFIG(filesystemmodel)
+static bool isRoot(const QFileSystemModel *model, const QString &path)
+{
+ const auto index = model->index(path);
+ return index.isValid() && model->fileInfo(index).isRoot();
+}
+
+static bool completeOnLoaded(const QFileSystemModel *model,
+ const QString &nativePrefix,
+ const QString &path,
+ Qt::CaseSensitivity caseSensitivity)
+{
+ const auto pathSize = path.size();
+ const auto prefixSize = nativePrefix.size();
+ if (prefixSize < pathSize)
+ return false;
+ const QString prefix = QDir::fromNativeSeparators(nativePrefix);
+ if (prefixSize == pathSize)
+ return path.compare(prefix, caseSensitivity) == 0 && isRoot(model, path);
+ // The user is typing something within that directory and is not in a subdirectory yet.
+ const auto separator = QLatin1Char('/');
+ return prefix.startsWith(path, caseSensitivity) && prefix.at(pathSize) == separator
+ && !prefix.rightRef(prefixSize - pathSize - 1).contains(separator);
+}
+
void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
{
Q_Q(QCompleter);
// Slot called when QFileSystemModel has finished loading.
// If we hide the popup because there was no match because the model was not loaded yet,
- // we re-start the completion when we get the results
- if (hiddenBecauseNoMatch
- && prefix.startsWith(path) && prefix != (path + QLatin1Char('/'))
- && widget) {
- q->complete();
+ // we re-start the completion when we get the results (unless triggered by
+ // something else, see QTBUG-14292).
+ if (hiddenBecauseNoMatch && widget) {
+ if (auto model = qobject_cast<const QFileSystemModel *>(proxy->sourceModel())) {
+ if (completeOnLoaded(model, prefix, path, cs))
+ q->complete();
+ }
}
}
+#else // QT_CONFIG(filesystemmodel)
+void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &) {}
+#endif
/*!
Constructs a completer object with the given \a parent.
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 14964a696d..287be3e272 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -73,6 +73,7 @@
#endif
#include "qpushbutton.h"
#include "qtooltip.h"
+#include <qwindow.h>
#include <private/qpushbutton_p.h>
#include <private/qaction_p.h>
#include <private/qguiapplication_p.h>
@@ -1485,6 +1486,8 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
{
Q_Q(QMenu);
+ emit q->aboutToShow();
+
#ifdef Q_OS_OSX
if (platformMenu) {
const auto actions = q->actions();
@@ -1498,8 +1501,6 @@ void QMenuPrivate::_q_platformMenuAboutToShow()
}
}
#endif
-
- emit q->aboutToShow();
}
bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
@@ -2328,8 +2329,10 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->motions = 0;
d->doChildEffects = true;
d->updateLayoutDirection();
- // Ensure that we get correct sizeHints by placing this window on the right screen.
- d->setScreenForPoint(p);
+
+ // Ensure that we get correct sizeHints by placing this window on the correct screen.
+ if (d->setScreenForPoint(p))
+ d->itemsDirty = true;
const bool contextMenu = d->isContextMenu();
if (d->lastContextMenu != contextMenu) {
diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp
index 7ed6f6d78d..e8d435429f 100644
--- a/src/widgets/widgets/qwidgetresizehandler.cpp
+++ b/src/widgets/widgets/qwidgetresizehandler.cpp
@@ -121,7 +121,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee)
break;
const QRect widgetRect = widget->rect().marginsAdded(QMargins(range, range, range, range));
const QPoint cursorPoint = widget->mapFromGlobal(e->globalPos());
- if (!widgetRect.contains(cursorPoint) || mode == Nowhere)
+ if (!widgetRect.contains(cursorPoint))
return false;
if (e->button() == Qt::LeftButton) {
#if 0 // Used to be included in Qt4 for Q_WS_X11
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index 7cc57f4d46..1828c4ca16 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -317,23 +317,26 @@ private:
if (quote)
break;
commandLine[i] = '\0';
- if (args.last()[0] != '\0')
+ if (!args.isEmpty() && args.last() && args.last()[0] != '\0')
args.append(commandLine.data() + i + 1);
// fall through
default:
- if (args.last()[0] == '\0')
+ if (!args.isEmpty() && args.last() && args.last()[0] == '\0')
args.last() = commandLine.data() + i;
escape = false; // only quotes are escaped
break;
}
}
- if (args.count() >= 2 && strncmp(args.at(1), "-ServerName:", 12) == 0)
+ if (args.count() >= 2 && args.at(1) && strncmp(args.at(1), "-ServerName:", 12) == 0)
args.remove(1);
bool develMode = false;
bool debugWait = false;
for (int i = args.count() - 1; i >= 0; --i) {
+ if (!args.at(i))
+ continue;
+
const char *arg = args.at(i);
if (strcmp(arg, "-qdevel") == 0) {
develMode = true;
diff --git a/src/xml/doc/src/qtxml-index.qdoc b/src/xml/doc/src/qtxml-index.qdoc
index dfb9b45fa7..65c6673db0 100644
--- a/src/xml/doc/src/qtxml-index.qdoc
+++ b/src/xml/doc/src/qtxml-index.qdoc
@@ -30,8 +30,10 @@
\title Qt XML
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.
- The module is not actively maintained anymore. Please use
- the QXmlStreamReader and QXmlStreamWriter classes in Qt Core instead.
+ Note that the module will not receive additional features anymore. For reading or writing XML
+ documents iteratively (SAX), we recommend using Qt Core's QXmlStreamReader and
+ QXmlStreamWriter classes. The classes are both easier to use and more compliant with the
+ XML standard.
To include the definitions of the module's classes, use the
following directive:
diff --git a/src/xml/doc/src/qtxml.qdoc b/src/xml/doc/src/qtxml.qdoc
index ad9b08b623..452e39d745 100644
--- a/src/xml/doc/src/qtxml.qdoc
+++ b/src/xml/doc/src/qtxml.qdoc
@@ -33,8 +33,10 @@
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.
- The module is not actively maintained anymore. Please use
- the \l{QXmlStreamReader} and \l{QXmlStreamWriter} classes in \l{Qt Core} instead.
+ Note that the module will not receive additional features anymore. For reading or writing XML
+ documents iteratively (SAX), we recommend using Qt Core's QXmlStreamReader and
+ QXmlStreamWriter classes. The classes are both easier to use and more compliant with the
+ XML standard.
To include the definitions of the module's classes, use the
following directive: