aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-06-29 15:23:44 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-06-29 15:23:44 +0200
commit89f8e1f54ff1f7e033f9a9da232bcb4c72b1e45f (patch)
tree570a9c7aa1d53b7d38ecb74b856203e19df59c52
parent48d24fe2e4d6ce6d91805a3425be0954126acc84 (diff)
parentd091c75c0b953a8b91c57f075769036bd09ae4c2 (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: src/quicktemplates2/qquickmenu.cpp Change-Id: I595ed1671fcad6c3b87123be2b825bca09552f0f
-rw-r--r--examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc71
-rw-r--r--src/imports/calendar/qquickmonthgrid.cpp75
-rw-r--r--src/imports/calendar/qquickmonthgrid_p.h4
-rw-r--r--src/quicktemplates2/qquickmenu.cpp7
-rw-r--r--src/quicktemplates2/qquickrangeslider.cpp4
-rw-r--r--src/quicktemplates2/qquickshortcutcontext.cpp3
-rw-r--r--tests/auto/applicationwindow/data/attachedProperties.qml6
-rw-r--r--tests/auto/calendar/data/tst_monthgrid.qml77
-rw-r--r--tests/auto/controls/data/tst_tooltip.qml38
-rw-r--r--tests/auto/menu/data/pressAndHold.qml73
-rw-r--r--tests/auto/menu/tst_menu.cpp22
11 files changed, 296 insertions, 84 deletions
diff --git a/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc b/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc
index 2e4d18ef..ef3978b3 100644
--- a/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc
+++ b/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc
@@ -40,11 +40,22 @@ application.
When setting up a new project, it's easiest to use
\l {Qt Creator Manual}{Qt Creator}. For this project, we chose the
\l {Qt Creator: Creating Qt Quick Projects}{Qt Quick application} template, which creates a
-basic "Hello World" application with all of the necessary files.
+basic "Hello World" application with the following files:
+
+\list
+\li \c MainForm.ui.qml - Defines the default UI
+\li \c main.qml - Embeds the default UI in a Window
+\li \c qml.qrc - Lists the \c .qml files that are built into the binary
+\li \c main.cpp - Loads \c main.qml
+\li \c chattutorial.pro - Provides the qmake configuration
+\endlist
+
+\note Delete the \c MainForm.ui.qml from the project as we will
+not use it in this tutorial.
\section2 main.cpp
-As we created a Qt Quick application, our \c main.cpp has two includes:
+The default code in \c main.cpp has two includes:
\quotefromfile chattutorial/chapter1-settingup/main.cpp
\skipto include
@@ -65,8 +76,9 @@ Within \c main(), we set up the application object and QML engine:
\skipto main
\printuntil }
-To enable Qt's support for \l {High DPI Displays}{high DPI scaling}, it
-is necessary to set an attribute before the application object is constructed.
+It begins with enabling \l {High DPI Displays}{high DPI scaling}, which is not
+part of the default code. It is necessary to do so before the application
+object is constructed.
After that's done, we construct the application object, passing any application
arguments provided by the user.
@@ -80,22 +92,26 @@ Once we've set up things in C++, we can move on to the user interface in QML.
\section2 main.qml
+Let's modify the default QML code to suit our needs.
+
\quotefromfile chattutorial/chapter1-settingup/main.qml
\skipto import
\printuntil import QtQuick.Controls 2.1
-First, we import the \l {Qt Quick} module. This gives us
+First, import the \l {Qt Quick} module. This gives us
access to graphical primitives such as \l Item, \l Rectangle, \l Text, and so
on.
For the full list of types, see the \l {Qt Quick QML Types} documentation.
-Next, we import the Qt Quick Controls 2 module. Amongst other things, this
-makes \l ApplicationWindow available:
+Next, import the Qt Quick Controls 2 module. Amongst other things, this
+provides access to \l ApplicationWindow, which will replace the existing
+root type, \c Window:
\skipto ApplicationWindow
\printuntil visible: true
-\printuntil }
-\printuntil }
+\dots
+\skipto }
+\skipuntil }
\printuntil }
ApplicationWindow is a \l Window with some added convenience for creating a
@@ -109,6 +125,8 @@ ApplicationWindow: \l {Window::}{width}, \l {Window::}{height}, and
Once we've set these, we have a properly sized, empty window ready to be
filled with content.
+\note The \c title property from the default code is removed.
+
The first \e "screen" in our application will be a list of contacts. It would
be nice to have some text at the top of each screen that describes its purpose.
The header and footer properties of ApplicationWindow could work in
@@ -121,25 +139,34 @@ items that should be displayed on every screen of an application:
\endlist
However, when the contents of the header and footer varies depending on
-which screen the user is viewing, it can be much easier to use \l Page.
+which screen the user is viewing, it is much easier to use \l Page.
For now, we'll just add one page, but in the next chapter, we'll demonstrate
how to navigate between several pages.
-Now that we have a Page, we can assign a \l Label to its \l {Page::}{header}
-property. Label extends the primitive \l Text item from the Qt Quick module by
-adding \l {Styling Qt Quick Controls 2}{styling} and \l {Control::}{font}
-inheritance. This means that a Label can look different depending on which
-style is in use, and can also propagate its pixel size to its children.
+\quotefromfile chattutorial/chapter1-settingup/main.qml
+\skipto Page
+\printuntil }
+\printuntil }
+
+We replace the default \c{MainForm {...}} code block with a Page, which is
+sized to occupy all the space on the window using the \l{anchors.fill}
+property.
+
+Then, we assign a \l Label to its \l {Page::}{header} property. Label extends
+the primitive \l Text item from the Qt Quick module by adding
+\l{Styling Qt Quick Controls 2}{styling} and \l {Control::}{font} inheritance.
+This means that a Label can look different depending on which style is in use,
+and can also propagate its pixel size to its children.
We want some distance between the top of the application window and the text,
-so we set the \l {Text::padding}{padding} property. This will allocate extra
-space on each side of the label (within its bounds). We could have also set the
-\l {Text::}{topPadding} and \l {Text::}{bottomPadding} properties explicitly.
+so we set the \l {Text::padding}{padding} property. This allocates extra
+space on each side of the label (within its bounds). We can also explicitly set
+the \l {Text::}{topPadding} and \l {Text::}{bottomPadding} properties instead.
We set the text of the label using the \c qsTr() function, which ensures that
the text can be translated by \l {Writing Source Code for Translation}{Qt's
-translation system}. It's a good idea to do this for text that will
-be visible to the end users of your application.
+translation system}. It's a good practice to follow for text that is visible to
+the end users of your application.
By default, text is vertically aligned to the top of its bounds, while the
horizontal alignment depends on the natural direction of the text; for example,
@@ -182,8 +209,8 @@ executable.
\printline target.path
-This line determines where the example will be copied to when running
-\c {make install}.
+This line replaces deployment settings that come with the default project file.
+It determines where the example is copied, on running "\c{make install}".
Now we can build and run the application:
diff --git a/src/imports/calendar/qquickmonthgrid.cpp b/src/imports/calendar/qquickmonthgrid.cpp
index 9621f49a..46b18db6 100644
--- a/src/imports/calendar/qquickmonthgrid.cpp
+++ b/src/imports/calendar/qquickmonthgrid.cpp
@@ -106,12 +106,17 @@ public:
void resizeItems();
- QQuickItem *cellAt(const QPoint &pos) const;
+ QQuickItem *cellAt(const QPointF &pos) const;
QDate dateOf(QQuickItem *cell) const;
- void updatePress(const QPoint &pos);
+ void updatePress(const QPointF &pos);
void clearPress(bool clicked);
+ void handlePress(const QPointF &point) override;
+ void handleMove(const QPointF &point) override;
+ void handleRelease(const QPointF &point) override;
+ void handleUngrab() override;
+
static void setContextProperty(QQuickItem *item, const QString &name, const QVariant &value);
QString title;
@@ -133,11 +138,13 @@ void QQuickMonthGridPrivate::resizeItems()
itemSize.setHeight((contentItem->height() - 5 * spacing) / 6);
const auto childItems = contentItem->childItems();
- for (QQuickItem *item : childItems)
- item->setSize(itemSize);
+ for (QQuickItem *item : childItems) {
+ if (!QQuickItemPrivate::get(item)->isTransparentForPositioner())
+ item->setSize(itemSize);
+ }
}
-QQuickItem *QQuickMonthGridPrivate::cellAt(const QPoint &pos) const
+QQuickItem *QQuickMonthGridPrivate::cellAt(const QPointF &pos) const
{
Q_Q(const QQuickMonthGrid);
if (contentItem) {
@@ -154,7 +161,7 @@ QDate QQuickMonthGridPrivate::dateOf(QQuickItem *cell) const
return QDate();
}
-void QQuickMonthGridPrivate::updatePress(const QPoint &pos)
+void QQuickMonthGridPrivate::updatePress(const QPointF &pos)
{
Q_Q(QQuickMonthGrid);
clearPress(false);
@@ -178,6 +185,33 @@ void QQuickMonthGridPrivate::clearPress(bool clicked)
pressedItem = nullptr;
}
+void QQuickMonthGridPrivate::handlePress(const QPointF &point)
+{
+ Q_Q(QQuickMonthGrid);
+ QQuickControlPrivate::handlePress(point);
+ updatePress(point);
+ if (pressedDate.isValid())
+ pressTimer = q->startTimer(qGuiApp->styleHints()->mousePressAndHoldInterval());
+}
+
+void QQuickMonthGridPrivate::handleMove(const QPointF &point)
+{
+ QQuickControlPrivate::handleMove(point);
+ updatePress(point);
+}
+
+void QQuickMonthGridPrivate::handleRelease(const QPointF &point)
+{
+ QQuickControlPrivate::handleRelease(point);
+ clearPress(true);
+}
+
+void QQuickMonthGridPrivate::handleUngrab()
+{
+ QQuickControlPrivate::handleUngrab();
+ clearPress(false);
+}
+
void QQuickMonthGridPrivate::setContextProperty(QQuickItem *item, const QString &name, const QVariant &value)
{
QQmlContext *context = qmlContext(item);
@@ -402,35 +436,6 @@ void QQuickMonthGrid::updatePolish()
d->resizeItems();
}
-void QQuickMonthGrid::mousePressEvent(QMouseEvent *event)
-{
- Q_D(QQuickMonthGrid);
- d->updatePress(event->pos());
- if (d->pressedDate.isValid())
- d->pressTimer = startTimer(qGuiApp->styleHints()->mousePressAndHoldInterval());
- event->accept();
-}
-
-void QQuickMonthGrid::mouseMoveEvent(QMouseEvent *event)
-{
- Q_D(QQuickMonthGrid);
- d->updatePress(event->pos());
- event->accept();
-}
-
-void QQuickMonthGrid::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QQuickMonthGrid);
- d->clearPress(true);
- event->accept();
-}
-
-void QQuickMonthGrid::mouseUngrabEvent()
-{
- Q_D(QQuickMonthGrid);
- d->clearPress(false);
-}
-
void QQuickMonthGrid::timerEvent(QTimerEvent *event)
{
Q_D(QQuickMonthGrid);
diff --git a/src/imports/calendar/qquickmonthgrid_p.h b/src/imports/calendar/qquickmonthgrid_p.h
index 20c9c0fd..b85e0921 100644
--- a/src/imports/calendar/qquickmonthgrid_p.h
+++ b/src/imports/calendar/qquickmonthgrid_p.h
@@ -101,10 +101,6 @@ protected:
void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override;
void updatePolish() override;
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- void mouseReleaseEvent(QMouseEvent *event) override;
- void mouseUngrabEvent() override;
void timerEvent(QTimerEvent *event) override;
private:
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp
index 4afac541..14449ad5 100644
--- a/src/quicktemplates2/qquickmenu.cpp
+++ b/src/quicktemplates2/qquickmenu.cpp
@@ -170,10 +170,8 @@ static const int SUBMENU_DELAY = 225;
\sa {Customizing Menu}, {Menu Controls}, {Popup Controls}
*/
-static const QQuickPopup::ClosePolicy defaultMenuClosePolicy =
- QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnReleaseOutside;
-static const QQuickPopup::ClosePolicy cascadingSubMenuClosePolicy =
- QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent | QQuickPopup::CloseOnReleaseOutsideParent;
+static const QQuickPopup::ClosePolicy defaultMenuClosePolicy = QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutside;
+static const QQuickPopup::ClosePolicy cascadingSubMenuClosePolicy = QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent;
static bool shouldCascade()
{
@@ -596,7 +594,6 @@ QQuickMenu::QQuickMenu(QObject *parent)
: QQuickPopup(*(new QQuickMenuPrivate), parent)
{
setFocus(true);
- setClosePolicy(defaultMenuClosePolicy);
}
/*!
diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp
index 3c9065db..154688b2 100644
--- a/src/quicktemplates2/qquickrangeslider.cpp
+++ b/src/quicktemplates2/qquickrangeslider.cpp
@@ -632,7 +632,7 @@ void QQuickRangeSlider::setTo(qreal to)
\li This property holds the value of the first handle in the range
\c from - \c to.
- If \l to is greater than \l from, the value of the first handle
+ If \l from is greater than \l to, the value of the first handle
must be greater than the second, and vice versa.
The default value is \c 0.0.
@@ -689,7 +689,7 @@ QQuickRangeSliderNode *QQuickRangeSlider::first() const
\li This property holds the value of the second handle in the range
\c from - \c to.
- If \l to is greater than \l from, the value of the first handle
+ If \l from is greater than \l to, the value of the first handle
must be greater than the second, and vice versa.
The default value is \c 0.0.
diff --git a/src/quicktemplates2/qquickshortcutcontext.cpp b/src/quicktemplates2/qquickshortcutcontext.cpp
index 978d1869..6553beb4 100644
--- a/src/quicktemplates2/qquickshortcutcontext.cpp
+++ b/src/quicktemplates2/qquickshortcutcontext.cpp
@@ -36,6 +36,7 @@
#include "qquickshortcutcontext_p_p.h"
#include "qquickoverlay_p_p.h"
+#include "qquicktooltip_p.h"
#include "qquickpopup_p.h"
#include <QtGui/qguiapplication.h>
@@ -50,6 +51,8 @@ static bool isBlockedByPopup(QQuickItem *item)
QQuickOverlay *overlay = QQuickOverlay::overlay(item->window());
const auto popups = QQuickOverlayPrivate::get(overlay)->stackingOrderPopups();
for (QQuickPopup *popup : popups) {
+ if (qobject_cast<QQuickToolTip *>(popup))
+ continue; // ignore tooltips (QTBUG-60492)
if (popup->isModal() || popup->closePolicy() & QQuickPopup::CloseOnEscape)
return item != popup->popupItem() && !popup->popupItem()->isAncestorOf(item);
}
diff --git a/tests/auto/applicationwindow/data/attachedProperties.qml b/tests/auto/applicationwindow/data/attachedProperties.qml
index 604a12bf..09bc47ef 100644
--- a/tests/auto/applicationwindow/data/attachedProperties.qml
+++ b/tests/auto/applicationwindow/data/attachedProperties.qml
@@ -68,7 +68,7 @@ ApplicationWindow {
property Item attached_overlay: ApplicationWindow.overlay
}
- Control {
+ Item {
id: childItem
property ApplicationWindow attached_window: ApplicationWindow.window
@@ -116,7 +116,7 @@ ApplicationWindow {
property Item attached_overlay: ApplicationWindow.overlay
}
- Control {
+ Item {
id: childWindowItem
property ApplicationWindow attached_window: ApplicationWindow.window
@@ -165,7 +165,7 @@ ApplicationWindow {
property Item attached_overlay: ApplicationWindow.overlay
}
- Control {
+ Item {
id: childAppWindowItem
property ApplicationWindow attached_window: ApplicationWindow.window
diff --git a/tests/auto/calendar/data/tst_monthgrid.qml b/tests/auto/calendar/data/tst_monthgrid.qml
index 413e6d55..e524f53e 100644
--- a/tests/auto/calendar/data/tst_monthgrid.qml
+++ b/tests/auto/calendar/data/tst_monthgrid.qml
@@ -79,6 +79,11 @@ TestCase {
}
}
+ Component {
+ id: signalSpy
+ SignalSpy { }
+ }
+
function test_locale() {
var control = delegateGrid.createObject(testCase, {month: 0, year: 2013})
@@ -102,13 +107,13 @@ TestCase {
for (var i = 0; i < 42; ++i) {
var cellDate = new Date(en_GB[i])
- compare(control.contentItem.children[i].date.getFullYear(), cellDate.getFullYear())
- compare(control.contentItem.children[i].date.getMonth(), cellDate.getMonth())
- compare(control.contentItem.children[i].date.getDate(), cellDate.getDate())
- compare(control.contentItem.children[i].day, cellDate.getDate())
+ compare(control.contentItem.children[i].date.getFullYear(), cellDate.getUTCFullYear())
+ compare(control.contentItem.children[i].date.getMonth(), cellDate.getUTCMonth())
+ compare(control.contentItem.children[i].date.getDate(), cellDate.getUTCDate())
+ compare(control.contentItem.children[i].day, cellDate.getUTCDate())
compare(control.contentItem.children[i].today, cellDate === new Date())
- compare(control.contentItem.children[i].month, cellDate.getMonth())
- compare(control.contentItem.children[i].year, cellDate.getFullYear())
+ compare(control.contentItem.children[i].month, cellDate.getUTCMonth())
+ compare(control.contentItem.children[i].year, cellDate.getUTCFullYear())
}
// en_US
@@ -125,13 +130,13 @@ TestCase {
for (var j = 0; j < 42; ++j) {
cellDate = new Date(en_US[j])
- compare(control.contentItem.children[j].date.getFullYear(), cellDate.getFullYear())
- compare(control.contentItem.children[j].date.getMonth(), cellDate.getMonth())
- compare(control.contentItem.children[j].date.getDate(), cellDate.getDate())
- compare(control.contentItem.children[j].day, cellDate.getDate())
+ compare(control.contentItem.children[j].date.getFullYear(), cellDate.getUTCFullYear())
+ compare(control.contentItem.children[j].date.getMonth(), cellDate.getUTCMonth())
+ compare(control.contentItem.children[j].date.getDate(), cellDate.getUTCDate())
+ compare(control.contentItem.children[j].day, cellDate.getUTCDate())
compare(control.contentItem.children[j].today, cellDate === new Date())
- compare(control.contentItem.children[j].month, cellDate.getMonth())
- compare(control.contentItem.children[j].year, cellDate.getFullYear())
+ compare(control.contentItem.children[j].month, cellDate.getUTCMonth())
+ compare(control.contentItem.children[j].year, cellDate.getUTCFullYear())
}
control.destroy()
@@ -227,4 +232,52 @@ TestCase {
control.destroy()
}
+
+ function test_clicked_data() {
+ return [
+ { tag: "mouse", touch: false },
+ { tag: "touch", touch: true }
+ ]
+ }
+
+ function test_clicked(data) {
+ var control = createTemporaryObject(defaultGrid, testCase)
+ verify(control)
+
+ compare(control.contentItem.children.length, 6 * 7 + 1)
+
+ var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressed"})
+ verify(pressedSpy.valid)
+
+ var releasedSpy = signalSpy.createObject(control, {target: control, signalName: "released"})
+ verify(releasedSpy.valid)
+
+ var clickedSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"})
+ verify(clickedSpy.valid)
+
+ var touch = touchEvent(control)
+
+ for (var i = 0; i < 42; ++i) {
+ var cell = control.contentItem.children[i]
+ verify(cell)
+
+ if (data.touch)
+ touch.press(0, cell).commit()
+ else
+ mousePress(cell)
+
+ compare(pressedSpy.count, i + 1)
+ compare(releasedSpy.count, i)
+ compare(clickedSpy.count, i)
+
+ if (data.touch)
+ touch.release(0, cell).commit()
+ else
+ mouseRelease(cell)
+
+ compare(pressedSpy.count, i + 1)
+ compare(releasedSpy.count, i + 1)
+ compare(clickedSpy.count, i + 1)
+ }
+ }
}
diff --git a/tests/auto/controls/data/tst_tooltip.qml b/tests/auto/controls/data/tst_tooltip.qml
index 66fb50c1..c7973c69 100644
--- a/tests/auto/controls/data/tst_tooltip.qml
+++ b/tests/auto/controls/data/tst_tooltip.qml
@@ -48,7 +48,7 @@
**
****************************************************************************/
-import QtQuick 2.4
+import QtQuick 2.9
import QtTest 1.0
import QtQuick.Controls 2.2
@@ -258,4 +258,40 @@ TestCase {
control.visible = true
tryCompare(control, "opacity", 1)
}
+
+ Component {
+ id: buttonAndShortcutComponent
+
+ Item {
+ property alias shortcut: shortcut
+ property alias button: button
+
+ Shortcut {
+ id: shortcut
+ sequence: "A"
+ }
+
+ Button {
+ id: button
+ text: "Just a button"
+ focusPolicy: Qt.NoFocus
+
+ ToolTip.visible: button.hovered
+ ToolTip.text: qsTr("Some helpful text")
+ }
+ }
+ }
+
+ function test_activateShortcutWhileToolTipVisible() {
+ var root = createTemporaryObject(buttonAndShortcutComponent, testCase)
+ verify(root)
+
+ mouseMove(root.button, root.button.width / 2, root.button.height / 2)
+ tryCompare(root.button.ToolTip.toolTip, "visible", true)
+
+ var shortcutActivatedSpy = signalSpy.createObject(root, { target: root.shortcut, signalName: "activated" })
+ verify(shortcutActivatedSpy.valid)
+ keyPress(Qt.Key_A)
+ compare(shortcutActivatedSpy.count, 1)
+ }
}
diff --git a/tests/auto/menu/data/pressAndHold.qml b/tests/auto/menu/data/pressAndHold.qml
new file mode 100644
index 00000000..6f0acd3a
--- /dev/null
+++ b/tests/auto/menu/data/pressAndHold.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.1
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias menu: menu
+
+ MouseArea {
+ anchors.fill: parent
+ onPressAndHold: menu.open()
+ }
+
+ Menu {
+ id: menu
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ MenuItem { text: "One" }
+ MenuItem { text: "Two" }
+ MenuItem { text: "Three" }
+ }
+}
diff --git a/tests/auto/menu/tst_menu.cpp b/tests/auto/menu/tst_menu.cpp
index 2baa2756..d4f363a1 100644
--- a/tests/auto/menu/tst_menu.cpp
+++ b/tests/auto/menu/tst_menu.cpp
@@ -65,6 +65,7 @@ public:
private slots:
void defaults();
void mouse();
+ void pressAndHold();
void contextMenuKeyboard();
void menuButton();
void addItem();
@@ -180,6 +181,27 @@ void tst_menu::mouse()
// QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1));
}
+void tst_menu::pressAndHold()
+{
+ QQuickApplicationHelper helper(this, QLatin1String("pressAndHold.qml"));
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickMenu *menu = window->property("menu").value<QQuickMenu *>();
+ QVERIFY(menu);
+
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
+ QTRY_VERIFY(menu->isVisible());
+
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
+ QVERIFY(menu->isVisible());
+
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
+ QTRY_VERIFY(!menu->isVisible());
+}
+
void tst_menu::contextMenuKeyboard()
{
if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls)