Use Inactive color group in inactive windows

A palette has three color groups (Active, Inactive, Disabled), but we
only listened to changes of the enabled state, and always used the
Active color group for an enabled item.

In order for the Inactive color group to take effect, we need to also
trigger the update when the "active" property changes. Instead of
connecting yet another signal, deliver WindowActivate/Deactivate to
as well, and forward from contentItem to all children which can then
update the current color group.

Add a test case.

Fixes: QTBUG-93752
Pick-to: 6.2
Change-Id: I4f2b6121e822115aaa5c4faaa5d402932dacc67b
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
Volker Hilsheimer 2021-06-11 14:19:17 +02:00
parent a991d3c1ec
commit 3675f2b235
5 changed files with 97 additions and 3 deletions

View File

@ -8505,6 +8505,13 @@ bool QQuickItem::event(QEvent *ev)
for (QQuickItem *item : d->childItems)
QCoreApplication::sendEvent(item, ev);
break;
case QEvent::WindowActivate:
case QEvent::WindowDeactivate:
if (d->palette())
d->setCurrentColorGroup();
for (QQuickItem *item : d->childItems)
QCoreApplication::sendEvent(item, ev);
break;
default:
return QObject::event(ev);
}

View File

@ -49,7 +49,7 @@
#include <QtQuick/private/qquickpalette_p.h>
#include <QtQuick/private/qquickabstractpaletteprovider_p.h>
#include <QtGui/qwindow.h>
#include <QtQml/private/qlazilyallocated_p.h>
QT_BEGIN_NAMESPACE
@ -150,6 +150,9 @@ public:
*/
virtual void updateChildrenPalettes(const QPalette &parentPalette);
protected:
void setCurrentColorGroup();
private:
using PalettePtr = std::unique_ptr<QQuickPalette>;
using Self = QQuickPaletteProviderPrivateBase<I, Impl>;
@ -160,7 +163,6 @@ private:
QQuickPalette *windowPalette() const;
void setCurrentColorGroup();
void connectItem();
@ -336,7 +338,10 @@ void QQuickPaletteProviderPrivateBase<I, Impl>::setCurrentColorGroup()
if constexpr (!isRootWindow<I>()) {
if (paletteData()) {
const bool enabled = itemWithPalette()->isEnabled();
paletteData()->setCurrentGroup(enabled ? QPalette::Active : QPalette::Disabled);
const auto window = itemWithPalette()->window();
const bool active = window ? window->isActive() : true;
paletteData()->setCurrentGroup(enabled ? (active ? QPalette::Active : QPalette::Inactive)
: QPalette::Disabled);
}
}
}

View File

@ -1512,6 +1512,10 @@ bool QQuickWindow::event(QEvent *e)
case QEvent::WindowDeactivate:
if (auto da = d->deliveryAgentPrivate())
da->handleWindowDeactivate(this);
Q_FALLTHROUGH();
case QEvent::WindowActivate:
if (d->contentItem)
QCoreApplication::sendEvent(d->contentItem, e);
break;
default:
break;

View File

@ -0,0 +1,34 @@
import QtQuick
Item {
width: 300
height: 300
visible: true
palette.active.base: "blue"
palette.inactive.base: "red"
palette.disabled.base: "gray"
Rectangle {
id: background
objectName: "background"
anchors.centerIn: parent
width: parent.width / 2
height: parent.height / 2
color: palette.base
Rectangle {
id: foreground
objectName: "foreground"
anchors.centerIn: parent
width: parent.width / 2
height: parent.height / 2
color: palette.base
border.color: "black"
}
}
}

View File

@ -34,6 +34,7 @@
#include <QtQuick/qquickview.h>
#include <QtGui/private/qinputmethod_p.h>
#include <QtQuick/private/qquickloader_p.h>
#include <QtQuick/private/qquickpalette_p.h>
#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQuick/private/qquicktextinput_p.h>
#include <QtQuick/private/qquickitemchangelistener_p.h>
@ -133,6 +134,7 @@ private slots:
void isAncestorOf();
void grab();
void colorGroup();
private:
QQmlEngine engine;
@ -3716,6 +3718,48 @@ void tst_QQuickItem::isAncestorOf()
QVERIFY(!sub2.isAncestorOf(&sub2));
}
/*
Verify that a nested item's palette responds to changes of the enabled state
and of the window's activation state by switching the current color group.
*/
void tst_QQuickItem::colorGroup()
{
QQuickView view;
view.setSource(testFileUrl("colorgroup.qml"));
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QQuickItem *root = qobject_cast<QQuickItem *>(view.rootObject());
QQuickItem *background = root->findChild<QQuickItem *>("background");
QVERIFY(background);
QQuickItem *foreground = root->findChild<QQuickItem *>("foreground");
QVERIFY(foreground);
QQuickPalette *palette = foreground->property("palette").value<QQuickPalette*>();
QVERIFY(palette);
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(palette->currentColorGroup(), QPalette::Active);
QCOMPARE(foreground->property("color").value<QColor>(), palette->active()->base());
background->setEnabled(false);
QCOMPARE(palette->currentColorGroup(), QPalette::Disabled);
QCOMPARE(foreground->property("color").value<QColor>(), palette->disabled()->base());
QWindow activationThief;
activationThief.show();
activationThief.requestActivate();
QVERIFY(QTest::qWaitForWindowActive(&activationThief));
QCOMPARE(palette->currentColorGroup(), QPalette::Disabled);
QCOMPARE(foreground->property("color").value<QColor>(), palette->disabled()->base());
background->setEnabled(true);
QCOMPARE(palette->currentColorGroup(), QPalette::Inactive);
QCOMPARE(foreground->property("color").value<QColor>(), palette->inactive()->base());
}
QTEST_MAIN(tst_QQuickItem)
#include "tst_qquickitem.moc"