[SCM] qtdeclarative packaging branch, master, updated. debian/5.5.1-3-6-g9be46d6
Timo Jyrinki
timo at moszumanska.debian.org
Wed Feb 17 10:43:18 UTC 2016
Gitweb-URL: http://git.debian.org/?p=pkg-kde/qt/qtdeclarative.git;a=commitdiff;h=5b15948
The following commit has been merged in the master branch:
commit 5b159487fd2edf374c07ed76f9e026d0045380f5
Author: Timo Jyrinki <timo.jyrinki at canonical.com>
Date: Wed Dec 16 14:06:53 2015 +0000
debian/patches/Add-isTabFence-private-flag.patch:
* debian/patches/Add-isTabFence-private-flag.patch:
- Tab should not leave dialog/popover/menu (LP: #1526208)
---
debian/changelog | 2 +
debian/patches/Add-isTabFence-private-flag.patch | 363 +++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 366 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index c5b3cef..cb5f126 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,8 @@ qtdeclarative-opensource-src (5.5.1-4) UNRELEASED; urgency=medium
- Avoid infinite velocity during release, after a drag. (LP: #1521917)
* debian/patches/MultiPointTouchArea-Fixed-released-duplication-on-mo.patch:
- Fix every key being pressed twice on desktop (LP: #1451554)
+ * debian/patches/Add-isTabFence-private-flag.patch:
+ - Tab should not leave dialog/popover/menu (LP: #1526208)
-- Debian Qt/KDE Maintainers <debian-qt-kde at lists.debian.org> Wed, 17 Feb 2016 10:15:48 +0000
diff --git a/debian/patches/Add-isTabFence-private-flag.patch b/debian/patches/Add-isTabFence-private-flag.patch
new file mode 100644
index 0000000..602772f
--- /dev/null
+++ b/debian/patches/Add-isTabFence-private-flag.patch
@@ -0,0 +1,363 @@
+From 6328dd2d2743ed540efea89742261f24552d7611 Mon Sep 17 00:00:00 2001
+From: Gabriel de Dietrich <gabriel.dedietrich at theqtcompany.com>
+Date: Thu, 2 Jul 2015 18:20:41 +0200
+Subject: [PATCH] Add isTabFence private flag
+
+When an item has this flag set, the user can't
+tab-navigate either out of it, or enter it.
+
+We use this flag to implement QQuickPanel as an
+item for platforms that only support one single
+top-level window.
+
+Change-Id: I1f4313912ae1c70217af0d4d21064932b50a9438
+Reviewed-by: Mitch Curtis <mitch.curtis at theqtcompany.com>
+---
+ src/quick/items/qquickitem.cpp | 89 +++++++++++++++++++------
+ src/quick/items/qquickitem_p.h | 8 +++
+ tests/auto/quick/qquickitem2/data/tabFence.qml | 49 ++++++++++++++
+ tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 72 ++++++++++++++++++++
+ 4 files changed, 199 insertions(+), 19 deletions(-)
+ create mode 100644 tests/auto/quick/qquickitem2/data/tabFence.qml
+
+diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
+index 0c9ee4f..80bad4d 100644
+--- a/src/quick/items/qquickitem.cpp
++++ b/src/quick/items/qquickitem.cpp
+@@ -2422,6 +2422,50 @@ bool QQuickItemPrivate::focusNextPrev(QQuickItem *item, bool forward)
+ return true;
+ }
+
++QQuickItem *QQuickItemPrivate::nextTabChildItem(const QQuickItem *item, int start)
++{
++ if (!item) {
++ qWarning() << "QQuickItemPrivate::nextTabChildItem called with null item.";
++ return Q_NULLPTR;
++ }
++ const QList<QQuickItem *> &children = item->childItems();
++ const int count = children.count();
++ if (start < 0 || start >= count) {
++ qWarning() << "QQuickItemPrivate::nextTabChildItem: Start index value out of range for item" << item;
++ return Q_NULLPTR;
++ }
++ while (start < count) {
++ QQuickItem *child = children.at(start);
++ if (!child->d_func()->isTabFence)
++ return child;
++ ++start;
++ }
++ return Q_NULLPTR;
++}
++
++QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int start)
++{
++ if (!item) {
++ qWarning() << "QQuickItemPrivate::prevTabChildItem called with null item.";
++ return Q_NULLPTR;
++ }
++ const QList<QQuickItem *> &children = item->childItems();
++ const int count = children.count();
++ if (start == -1)
++ start = count - 1;
++ if (start < 0 || start >= count) {
++ qWarning() << "QQuickItemPrivate::prevTabChildItem: Start index value out of range for item" << item;
++ return Q_NULLPTR;
++ }
++ while (start >= 0) {
++ QQuickItem *child = children.at(start);
++ if (!child->d_func()->isTabFence)
++ return child;
++ --start;
++ }
++ return Q_NULLPTR;
++}
++
+ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward)
+ {
+ Q_ASSERT(item);
+@@ -2444,7 +2488,6 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ from = item->parentItem();
+ }
+ bool skip = false;
+- const QQuickItem * const originalItem = item;
+ QQuickItem * startItem = item;
+ QQuickItem * firstFromItem = from;
+ QQuickItem *current = item;
+@@ -2453,46 +2496,53 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ QQuickItem *last = current;
+
+ bool hasChildren = !current->childItems().isEmpty() && current->isEnabled() && current->isVisible();
++ QQuickItem *firstChild = Q_NULLPTR;
++ QQuickItem *lastChild = Q_NULLPTR;
++ if (hasChildren) {
++ firstChild = nextTabChildItem(current, 0);
++ if (!firstChild)
++ hasChildren = false;
++ else
++ lastChild = prevTabChildItem(current, -1);
++ }
++ bool isTabFence = current->d_func()->isTabFence;
+
+ // coming from parent: check children
+ if (hasChildren && from == current->parentItem()) {
+ if (forward) {
+- current = current->childItems().first();
++ current = firstChild;
+ } else {
+- current = current->childItems().last();
++ current = lastChild;
+ if (!current->childItems().isEmpty())
+ skip = true;
+ }
+- } else if (hasChildren && forward && from != current->childItems().last()) {
++ } else if (hasChildren && forward && from != lastChild) {
+ // not last child going forwards
+ int nextChild = current->childItems().indexOf(from) + 1;
+- current = current->childItems().at(nextChild);
+- } else if (hasChildren && !forward && from != current->childItems().first()) {
++ current = nextTabChildItem(current, nextChild);
++ } else if (hasChildren && !forward && from != firstChild) {
+ // not first child going backwards
+ int prevChild = current->childItems().indexOf(from) - 1;
+- current = current->childItems().at(prevChild);
++ current = prevTabChildItem(current, prevChild);
+ if (!current->childItems().isEmpty())
+ skip = true;
+ // back to the parent
+- } else if (current->parentItem()) {
+- current = current->parentItem();
++ } else if (QQuickItem *parent = !isTabFence ? current->parentItem() : Q_NULLPTR) {
+ // we would evaluate the parent twice, thus we skip
+ if (forward) {
+ skip = true;
+- } else if (!forward && !current->childItems().isEmpty()) {
+- if (last != current->childItems().first()) {
+- skip = true;
+- } else if (last == current->childItems().first()) {
+- if (current->isFocusScope() && current->activeFocusOnTab() && current->hasActiveFocus())
++ } else if (QQuickItem *firstSibling = !forward ? nextTabChildItem(parent, 0) : Q_NULLPTR) {
++ if (last != firstSibling
++ || (parent->isFocusScope() && parent->activeFocusOnTab() && parent->hasActiveFocus()))
+ skip = true;
+- }
+ }
++ current = parent;
+ } else if (hasChildren) {
+ // Wrap around after checking all items forward
+ if (forward) {
+- current = current->childItems().first();
++ current = firstChild;
+ } else {
+- current = current->childItems().last();
++ current = lastChild;
+ if (!current->childItems().isEmpty())
+ skip = true;
+ }
+@@ -2500,9 +2550,9 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ from = last;
+ if (current == startItem && from == firstFromItem) {
+ // wrapped around, avoid endless loops
+- if (originalItem == contentItem) {
++ if (item == contentItem) {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
+- return item->window()->contentItem();
++ return item;
+ } else {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return " << startItem;
+ return startItem;
+@@ -3026,6 +3076,7 @@ QQuickItemPrivate::QQuickItemPrivate()
+ , activeFocusOnTab(false)
+ , implicitAntialiasing(false)
+ , antialiasingValid(false)
++ , isTabFence(false)
+ , dirtyAttributes(0)
+ , nextDirtyItem(0)
+ , prevDirtyItem(0)
+diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
+index 942b51b..6670975 100644
+--- a/src/quick/items/qquickitem_p.h
++++ b/src/quick/items/qquickitem_p.h
+@@ -427,6 +427,12 @@ public:
+ bool activeFocusOnTab:1;
+ bool implicitAntialiasing:1;
+ bool antialiasingValid:1;
++ // isTabFence: When true, the item acts as a fence within the tab focus chain.
++ // This means that the item and its children will be skipped from the tab focus
++ // chain when navigating from its parent or any of its siblings. Similarly,
++ // when any of the item's descendants gets focus, the item constrains the tab
++ // focus chain and prevents tabbing outside.
++ bool isTabFence:1;
+
+ enum DirtyType {
+ TransformOrigin = 0x00000001,
+@@ -498,6 +504,8 @@ public:
+ void itemToParentTransform(QTransform &) const;
+
+ static bool focusNextPrev(QQuickItem *item, bool forward);
++ static QQuickItem *nextTabChildItem(const QQuickItem *item, int start);
++ static QQuickItem *prevTabChildItem(const QQuickItem *item, int start);
+ static QQuickItem *nextPrevItemInTabFocusChain(QQuickItem *item, bool forward);
+
+ static bool canAcceptTabFocus(QQuickItem *item);
+diff --git a/tests/auto/quick/qquickitem2/data/tabFence.qml b/tests/auto/quick/qquickitem2/data/tabFence.qml
+new file mode 100644
+index 0000000..fcf69b4
+--- /dev/null
++++ b/tests/auto/quick/qquickitem2/data/tabFence.qml
+@@ -0,0 +1,49 @@
++import QtQuick 2.1
++import Test 1.0
++
++Item {
++ objectName: "root"
++ focus: true
++ width: 800
++ height: 600
++
++ TabFence {
++ objectName: "fence1"
++
++ TextInput {
++ objectName: "input11"
++ activeFocusOnTab: true
++ }
++ TextInput {
++ objectName: "input12"
++ activeFocusOnTab: true
++ }
++ TextInput {
++ objectName: "input13"
++ activeFocusOnTab: true
++ }
++ }
++
++ TextInput {
++ objectName: "input1"
++ activeFocusOnTab: true
++ }
++
++ TextInput {
++ objectName: "input2"
++ activeFocusOnTab: true
++ }
++
++ TabFence {
++ objectName: "fence2"
++ }
++
++ TextInput {
++ objectName: "input3"
++ activeFocusOnTab: true
++ }
++
++ TabFence {
++ objectName: "fence3"
++ }
++}
+diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+index 396f183..9f3de82 100644
+--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
++++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+@@ -73,6 +73,8 @@ private slots:
+ void nextItemInFocusChain2();
+ void nextItemInFocusChain3();
+
++ void tabFence();
++
+ void keys();
+ void standardKeys_data();
+ void standardKeys();
+@@ -289,6 +291,20 @@ private:
+
+ QML_DECLARE_TYPE(HollowTestItem);
+
++class TabFenceItem : public QQuickItem
++{
++ Q_OBJECT
++
++public:
++ TabFenceItem(QQuickItem *parent = Q_NULLPTR)
++ : QQuickItem(parent)
++ {
++ QQuickItemPrivate *d = QQuickItemPrivate::get(this);
++ d->isTabFence = true;
++ }
++};
++
++QML_DECLARE_TYPE(TabFenceItem);
+
+ tst_QQuickItem::tst_QQuickItem()
+ {
+@@ -299,6 +315,7 @@ void tst_QQuickItem::initTestCase()
+ QQmlDataTest::initTestCase();
+ qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem");
+ qmlRegisterType<HollowTestItem>("Test", 1, 0, "HollowTestItem");
++ qmlRegisterType<TabFenceItem>("Test", 1, 0, "TabFence");
+ }
+
+ void tst_QQuickItem::cleanup()
+@@ -1120,6 +1137,61 @@ void tst_QQuickItem::nextItemInFocusChain3()
+ QVERIFY(QGuiApplication::focusWindow() == window);
+ }
+
++void verifyTabFocusChain(QQuickView *window, const char **focusChain, bool forward)
++{
++ int idx = 0;
++ for (const char **objectName = focusChain; *objectName; ++objectName, ++idx) {
++ const QString &descrStr = QString("idx=%1 objectName=\"%2\"").arg(idx).arg(*objectName);
++ const char *descr = descrStr.toLocal8Bit().data();
++ QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, forward ? Qt::NoModifier : Qt::ShiftModifier);
++ QGuiApplication::sendEvent(window, &key);
++ QVERIFY2(key.isAccepted(), descr);
++
++ QQuickItem *item = findItem<QQuickItem>(window->rootObject(), *objectName);
++ QVERIFY2(item, descr);
++ QVERIFY2(item->hasActiveFocus(), descr);
++ }
++}
++
++void tst_QQuickItem::tabFence()
++{
++ QQuickView *window = new QQuickView(0);
++ window->setBaseSize(QSize(800,600));
++
++ window->setSource(testFileUrl("tabFence.qml"));
++ window->show();
++ window->requestActivate();
++ QVERIFY(QTest::qWaitForWindowActive(window));
++ QVERIFY(QGuiApplication::focusWindow() == window);
++ QVERIFY(window->rootObject()->hasActiveFocus());
++
++ const char *rootTabFocusChain[] = {
++ "input1", "input2", "input3", "input1", Q_NULLPTR
++ };
++ verifyTabFocusChain(window, rootTabFocusChain, true /* forward */);
++
++ const char *rootBacktabFocusChain[] = {
++ "input3", "input2", "input1", "input3", Q_NULLPTR
++ };
++ verifyTabFocusChain(window, rootBacktabFocusChain, false /* forward */);
++
++ // Give focus to input11 in fence1
++ QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "input11");
++ item->setFocus(true);
++ QVERIFY(item);
++ QVERIFY(item->hasActiveFocus());
++
++ const char *fence1TabFocusChain[] = {
++ "input12", "input13", "input11", "input12", Q_NULLPTR
++ };
++ verifyTabFocusChain(window, fence1TabFocusChain, true /* forward */);
++
++ const char *fence1BacktabFocusChain[] = {
++ "input11", "input13", "input12", "input11", Q_NULLPTR
++ };
++ verifyTabFocusChain(window, fence1BacktabFocusChain, false /* forward */);
++}
++
+ void tst_QQuickItem::keys()
+ {
+ QQuickView *window = new QQuickView(0);
+--
+2.6.4
+
diff --git a/debian/patches/series b/debian/patches/series
index eebe606..5ca5158 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,6 +2,7 @@
qmlplugindump-Don-t-try-to-import-Qt.test.qtestroot.patch
Flickable-avoid-perturbing-the-timeline-further-whil.patch
MultiPointTouchArea-Fixed-released-duplication-on-mo.patch
+Add-isTabFence-private-flag.patch
# Debian patches
check_system_double-conversion.patch
--
qtdeclarative packaging
More information about the pkg-kde-commits
mailing list