aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/imports/controls/ComboBox.qml2
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-material.qdoc3
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-universal.qdoc3
-rw-r--r--src/imports/controls/material/ComboBox.qml2
-rw-r--r--src/imports/controls/material/qquickmaterialstyle.cpp103
-rw-r--r--src/imports/controls/material/qquickmaterialstyle_p.h10
-rw-r--r--src/imports/controls/universal/ComboBox.qml2
-rw-r--r--src/imports/controls/universal/qquickuniversalstyle.cpp61
-rw-r--r--src/imports/controls/universal/qquickuniversalstyle_p.h7
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp5
-rw-r--r--src/quicktemplates2/qquickmenu.cpp1
-rw-r--r--src/quicktemplates2/qquickmenu_p_p.h3
-rw-r--r--src/quicktemplates2/qquickpopup.cpp35
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h10
-rw-r--r--src/quicktemplates2/qquicktooltip.cpp40
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/controls/data/tst_popup.qml6
-rw-r--r--tests/auto/controls/data/tst_tooltip.qml25
-rw-r--r--tests/auto/popup/tst_popup.cpp9
-rw-r--r--tests/auto/qquickmaterialstyleconf/data/applicationwindow.qml53
-rw-r--r--tests/auto/qquickmaterialstyleconf/qquickmaterialstyleconf.pro17
-rw-r--r--tests/auto/qquickmaterialstyleconf/qquickmaterialstyleconf.qrc5
-rw-r--r--tests/auto/qquickmaterialstyleconf/qtquickcontrols2.conf6
-rw-r--r--tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp72
-rw-r--r--tests/auto/qquickuniversalstyleconf/data/applicationwindow.qml53
-rw-r--r--tests/auto/qquickuniversalstyleconf/qquickuniversalstyleconf.pro17
-rw-r--r--tests/auto/qquickuniversalstyleconf/qquickuniversalstyleconf.qrc5
-rw-r--r--tests/auto/qquickuniversalstyleconf/qtquickcontrols2.conf6
-rw-r--r--tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp72
29 files changed, 523 insertions, 112 deletions
diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml
index 1470ad7c..aeeabbb7 100644
--- a/src/imports/controls/ComboBox.qml
+++ b/src/imports/controls/ComboBox.qml
@@ -58,7 +58,7 @@ T.ComboBox {
//! [delegate]
delegate: ItemDelegate {
- width: control.width
+ width: control.popup.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
highlighted: control.highlightedIndex == index
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-material.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-material.qdoc
index 818ad7fd..74a7ece1 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-material.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-material.qdoc
@@ -134,7 +134,8 @@
In addition to specifying the attributes in QML, it is also possible to
specify them via environment variables or in a \l {qtquickcontrols2-conf}
- {configuration file}.
+ {configuration file}. Attributes specified in QML take precedence over all
+ other methods.
\section3 Environment Variables
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-universal.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-universal.qdoc
index db1e2766..cb6ac17e 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-universal.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-universal.qdoc
@@ -134,7 +134,8 @@
In addition to specifying the attributes in QML, it is also possible to
specify them via environment variables or in a \l {qtquickcontrols2-conf}
- {configuration file}.
+ {configuration file}. Attributes specified in QML take precedence over all
+ other methods.
\section3 Environment Variables
diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml
index c18a2624..a48c6884 100644
--- a/src/imports/controls/material/ComboBox.qml
+++ b/src/imports/controls/material/ComboBox.qml
@@ -62,7 +62,7 @@ T.ComboBox {
Material.foreground: flat ? undefined : Material.foreground
delegate: MenuItem {
- width: control.width
+ width: control.popup.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
Material.foreground: control.currentIndex === index ? control.popup.Material.accent : control.popup.Material.foreground
highlighted: control.highlightedIndex === index
diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp
index d71545b7..76332c51 100644
--- a/src/imports/controls/material/qquickmaterialstyle.cpp
+++ b/src/imports/controls/material/qquickmaterialstyle.cpp
@@ -369,15 +369,24 @@ static const QRgb colors[][14] = {
}
};
-static QQuickMaterialStyle::Theme defaultTheme = QQuickMaterialStyle::Light;
-static uint defaultPrimary = QQuickMaterialStyle::Indigo;
-static uint defaultAccent = QQuickMaterialStyle::Pink;
-static uint defaultForeground = 0xDD000000; // primaryTextColorLight
-static uint defaultBackground = 0xFFFAFAFA; // backgroundColorLight
-static bool defaultPrimaryCustom = false;
-static bool defaultAccentCustom = false;
-static bool defaultForegroundCustom = true;
-static bool defaultBackgroundCustom = true;
+// If no value was inherited from a parent or explicitly set, the "global" values are used.
+// The initial, default values of the globals are hard-coded here, but the environment
+// variables and .conf file override them if specified.
+static QQuickMaterialStyle::Theme globalTheme = QQuickMaterialStyle::Light;
+static uint globalPrimary = QQuickMaterialStyle::Indigo;
+static uint globalAccent = QQuickMaterialStyle::Pink;
+static uint globalForeground = 0xDD000000; // primaryTextColorLight
+static uint globalBackground = 0xFFFAFAFA; // backgroundColorLight
+// These represent whether a global foreground/background was set.
+// Each style's m_hasForeground/m_hasBackground are initialized to these values.
+static bool hasGlobalForeground = false;
+static bool hasGlobalBackground = false;
+// These represent whether or not the global color value was specified as one of the
+// values that QColor accepts, as opposed to one of the pre-defined colors like Red.
+static bool globalPrimaryCustom = false;
+static bool globalAccentCustom = false;
+static bool globalForegroundCustom = true;
+static bool globalBackgroundCustom = true;
static const QRgb backgroundColorLight = 0xFFFAFAFA;
static const QRgb backgroundColorDark = 0xFF303030;
@@ -421,17 +430,17 @@ QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickStyleAttached(
m_explicitAccent(false),
m_explicitForeground(false),
m_explicitBackground(false),
- m_customPrimary(defaultPrimaryCustom),
- m_customAccent(defaultAccentCustom),
- m_customForeground(defaultForegroundCustom),
- m_customBackground(defaultBackgroundCustom),
- m_hasForeground(false),
- m_hasBackground(false),
- m_theme(defaultTheme),
- m_primary(defaultPrimary),
- m_accent(defaultAccent),
- m_foreground(defaultForeground),
- m_background(defaultBackground),
+ m_customPrimary(globalPrimaryCustom),
+ m_customAccent(globalAccentCustom),
+ m_customForeground(globalForegroundCustom),
+ m_customBackground(globalBackgroundCustom),
+ m_hasForeground(hasGlobalForeground),
+ m_hasBackground(hasGlobalBackground),
+ m_theme(globalTheme),
+ m_primary(globalPrimary),
+ m_accent(globalAccent),
+ m_foreground(globalForeground),
+ m_background(globalBackground),
m_elevation(0)
{
init();
@@ -498,7 +507,7 @@ void QQuickMaterialStyle::resetTheme()
m_explicitTheme = false;
QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle());
- inheritTheme(material ? material->theme() : defaultTheme);
+ inheritTheme(material ? material->theme() : globalTheme);
}
QVariant QQuickMaterialStyle::primary() const
@@ -557,7 +566,7 @@ void QQuickMaterialStyle::resetPrimary()
if (material)
inheritPrimary(material->m_primary, material->m_customPrimary);
else
- inheritPrimary(defaultPrimary, false);
+ inheritPrimary(globalPrimary, false);
}
QVariant QQuickMaterialStyle::accent() const
@@ -616,7 +625,7 @@ void QQuickMaterialStyle::resetAccent()
if (material)
inheritAccent(material->m_accent, material->m_customAccent);
else
- inheritAccent(defaultAccent, false);
+ inheritAccent(globalAccent, false);
}
QVariant QQuickMaterialStyle::foreground() const
@@ -673,7 +682,7 @@ void QQuickMaterialStyle::resetForeground()
m_customForeground = false;
m_explicitForeground = false;
QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle());
- inheritForeground(material ? material->m_foreground : defaultForeground, true, material ? material->m_hasForeground : false);
+ inheritForeground(material ? material->m_foreground : globalForeground, true, material ? material->m_hasForeground : false);
}
QVariant QQuickMaterialStyle::background() const
@@ -731,7 +740,7 @@ void QQuickMaterialStyle::resetBackground()
m_customBackground = false;
m_explicitBackground = false;
QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle());
- inheritBackground(material ? material->m_background : defaultBackground, true, material ? material->m_hasBackground : false);
+ inheritBackground(material ? material->m_background : globalBackground, true, material ? material->m_hasBackground : false);
}
int QQuickMaterialStyle::elevation() const
@@ -1135,28 +1144,28 @@ static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSe
void QQuickMaterialStyle::init()
{
- static bool defaultsInitialized = false;
- if (!defaultsInitialized) {
+ static bool globalsInitialized = false;
+ if (!globalsInitialized) {
QSharedPointer<QSettings> settings = QQuickStyleAttached::settings(QStringLiteral("Material"));
bool ok = false;
QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_THEME", settings, QStringLiteral("Theme"));
Theme themeEnum = toEnumValue<Theme>(themeValue, &ok);
if (ok)
- defaultTheme = m_theme = effectiveTheme(themeEnum);
+ globalTheme = m_theme = effectiveTheme(themeEnum);
else if (!themeValue.isEmpty())
qWarning().nospace().noquote() << "Material: unknown theme value: " << themeValue;
QByteArray primaryValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_PRIMARY", settings, QStringLiteral("Primary"));
Color primaryEnum = toEnumValue<Color>(primaryValue, &ok);
if (ok) {
- defaultPrimaryCustom = m_customPrimary = false;
- defaultPrimary = m_primary = primaryEnum;
+ globalPrimaryCustom = m_customPrimary = false;
+ globalPrimary = m_primary = primaryEnum;
} else {
QColor color(primaryValue.constData());
if (color.isValid()) {
- defaultPrimaryCustom = m_customPrimary = true;
- defaultPrimary = m_primary = color.rgba();
+ globalPrimaryCustom = m_customPrimary = true;
+ globalPrimary = m_primary = color.rgba();
} else if (!primaryValue.isEmpty()) {
qWarning().nospace().noquote() << "Material: unknown primary value: " << primaryValue;
}
@@ -1165,13 +1174,13 @@ void QQuickMaterialStyle::init()
QByteArray accentValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_ACCENT", settings, QStringLiteral("Accent"));
Color accentEnum = toEnumValue<Color>(accentValue, &ok);
if (ok) {
- defaultAccentCustom = m_customAccent = false;
- defaultAccent = m_accent = accentEnum;
+ globalAccentCustom = m_customAccent = false;
+ globalAccent = m_accent = accentEnum;
} else if (!accentValue.isEmpty()) {
QColor color(accentValue.constData());
if (color.isValid()) {
- defaultAccentCustom = m_customAccent = true;
- defaultAccent = m_accent = color.rgba();
+ globalAccentCustom = m_customAccent = true;
+ globalAccent = m_accent = color.rgba();
} else {
qWarning().nospace().noquote() << "Material: unknown accent value: " << accentValue;
}
@@ -1180,13 +1189,15 @@ void QQuickMaterialStyle::init()
QByteArray foregroundValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_FOREGROUND", settings, QStringLiteral("Foreground"));
Color foregroundEnum = toEnumValue<Color>(foregroundValue, &ok);
if (ok) {
- defaultForegroundCustom = m_customForeground = false;
- defaultForeground = m_foreground = foregroundEnum;
+ globalForegroundCustom = m_customForeground = false;
+ globalForeground = m_foreground = foregroundEnum;
+ hasGlobalForeground = m_hasForeground = true;
} else if (!foregroundValue.isEmpty()) {
QColor color(foregroundValue.constData());
if (color.isValid()) {
- defaultForegroundCustom = m_customForeground = true;
- defaultForeground = m_foreground = color.rgba();
+ globalForegroundCustom = m_customForeground = true;
+ globalForeground = m_foreground = color.rgba();
+ hasGlobalForeground = m_hasForeground = true;
} else {
qWarning().nospace().noquote() << "Material: unknown foreground value: " << foregroundValue;
}
@@ -1195,19 +1206,21 @@ void QQuickMaterialStyle::init()
QByteArray backgroundValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_BACKGROUND", settings, QStringLiteral("Background"));
Color backgroundEnum = toEnumValue<Color>(backgroundValue, &ok);
if (ok) {
- defaultBackgroundCustom = m_customBackground = false;
- defaultBackground = m_background = backgroundEnum;
+ globalBackgroundCustom = m_customBackground = false;
+ globalBackground = m_background = backgroundEnum;
+ hasGlobalBackground = m_hasBackground = true;
} else if (!backgroundValue.isEmpty()) {
QColor color(backgroundValue.constData());
if (color.isValid()) {
- defaultBackgroundCustom = m_customBackground = true;
- defaultBackground = m_background = color.rgba();
+ globalBackgroundCustom = m_customBackground = true;
+ globalBackground = m_background = color.rgba();
+ hasGlobalBackground = m_hasBackground = true;
} else {
qWarning().nospace().noquote() << "Material: unknown background value: " << backgroundValue;
}
}
- defaultsInitialized = true;
+ globalsInitialized = true;
}
QQuickStyleAttached::init(); // TODO: lazy init?
diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h
index d338e745..78ba88da 100644
--- a/src/imports/controls/material/qquickmaterialstyle_p.h
+++ b/src/imports/controls/material/qquickmaterialstyle_p.h
@@ -246,17 +246,27 @@ private:
QColor buttonColor(bool highlighted) const;
Shade themeShade() const;
+ // These reflect whether a color value was explicitly set on the specific
+ // item that this attached style object represents.
bool m_explicitTheme;
bool m_explicitPrimary;
bool m_explicitAccent;
bool m_explicitForeground;
bool m_explicitBackground;
+ // These reflect whether the color value that was either inherited or
+ // explicitly set is in the form that QColor expects, rather than one of
+ // our pre-defined color enum values.
bool m_customPrimary;
bool m_customAccent;
bool m_customForeground;
bool m_customBackground;
+ // These will be true when this item has an explicit or inherited foreground/background
+ // color, or these colors were declared globally via settings (e.g. conf or env vars).
+ // Some color properties of the style will return different values depending on whether
+ // or not these are set.
bool m_hasForeground;
bool m_hasBackground;
+ // The actual values for this item, whether explicit, inherited or globally set.
Theme m_theme;
uint m_primary;
uint m_accent;
diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml
index 0fe49520..e259d092 100644
--- a/src/imports/controls/universal/ComboBox.qml
+++ b/src/imports/controls/universal/ComboBox.qml
@@ -59,7 +59,7 @@ T.ComboBox {
bottomPadding: padding - 5
delegate: ItemDelegate {
- width: control.width
+ width: control.popup.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
highlighted: control.highlightedIndex === index
hoverEnabled: control.hoverEnabled
diff --git a/src/imports/controls/universal/qquickuniversalstyle.cpp b/src/imports/controls/universal/qquickuniversalstyle.cpp
index 32c00de9..b33c27e8 100644
--- a/src/imports/controls/universal/qquickuniversalstyle.cpp
+++ b/src/imports/controls/universal/qquickuniversalstyle.cpp
@@ -141,15 +141,22 @@ static QQuickUniversalStyle::Theme qquickuniversal_effective_theme(QQuickUnivers
return theme;
}
-static QQuickUniversalStyle::Theme DefaultTheme = QQuickUniversalStyle::Light;
-static QRgb DefaultAccent = qquickuniversal_accent_color(QQuickUniversalStyle::Cobalt);
-static QRgb DefaultForeground = qquickuniversal_light_color(QQuickUniversalStyle::BaseHigh);
-static QRgb DefaultBackground = qquickuniversal_light_color(QQuickUniversalStyle::AltHigh);
+// If no value was inherited from a parent or explicitly set, the "global" values are used.
+// The initial, default values of the globals are hard-coded here, but the environment
+// variables and .conf file override them if specified.
+static QQuickUniversalStyle::Theme GlobalTheme = QQuickUniversalStyle::Light;
+static QRgb GlobalAccent = qquickuniversal_accent_color(QQuickUniversalStyle::Cobalt);
+static QRgb GlobalForeground = qquickuniversal_light_color(QQuickUniversalStyle::BaseHigh);
+static QRgb GlobalBackground = qquickuniversal_light_color(QQuickUniversalStyle::AltHigh);
+// These represent whether a global foreground/background was set.
+// Each style's m_hasForeground/m_hasBackground are initialized to these values.
+static bool HasGlobalForeground = false;
+static bool HasGlobalBackground = false;
QQuickUniversalStyle::QQuickUniversalStyle(QObject *parent) : QQuickStyleAttached(parent),
m_explicitTheme(false), m_explicitAccent(false), m_explicitForeground(false), m_explicitBackground(false),
- m_hasForeground(false), m_hasBackground(false), m_theme(DefaultTheme),
- m_accent(DefaultAccent), m_foreground(DefaultForeground), m_background(DefaultBackground)
+ m_hasForeground(HasGlobalForeground), m_hasBackground(HasGlobalBackground), m_theme(GlobalTheme),
+ m_accent(GlobalAccent), m_foreground(GlobalForeground), m_background(GlobalBackground)
{
init();
}
@@ -209,7 +216,7 @@ void QQuickUniversalStyle::resetTheme()
m_explicitTheme = false;
QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(parentStyle());
- inheritTheme(universal ? universal->theme() : DefaultTheme);
+ inheritTheme(universal ? universal->theme() : GlobalTheme);
}
QVariant QQuickUniversalStyle::accent() const
@@ -259,7 +266,7 @@ void QQuickUniversalStyle::resetAccent()
m_explicitAccent = false;
QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(parentStyle());
- inheritAccent(universal ? universal->m_accent : DefaultAccent);
+ inheritAccent(universal ? universal->m_accent : GlobalAccent);
}
QVariant QQuickUniversalStyle::foreground() const
@@ -314,7 +321,7 @@ void QQuickUniversalStyle::resetForeground()
m_hasForeground = false;
m_explicitForeground = false;
QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(parentStyle());
- inheritForeground(universal ? universal->m_foreground : DefaultForeground, universal ? universal->m_hasForeground : false);
+ inheritForeground(universal ? universal->m_foreground : GlobalForeground, universal ? universal->m_hasForeground : false);
}
QVariant QQuickUniversalStyle::background() const
@@ -369,7 +376,7 @@ void QQuickUniversalStyle::resetBackground()
m_hasBackground = false;
m_explicitBackground = false;
QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(parentStyle());
- inheritBackground(universal ? universal->m_background : DefaultBackground, universal ? universal->m_hasBackground : false);
+ inheritBackground(universal ? universal->m_background : GlobalBackground, universal ? universal->m_hasBackground : false);
}
QColor QQuickUniversalStyle::color(Color color) const
@@ -531,26 +538,26 @@ static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSe
void QQuickUniversalStyle::init()
{
- static bool defaultsInitialized = false;
- if (!defaultsInitialized) {
+ static bool globalsInitialized = false;
+ if (!globalsInitialized) {
QSharedPointer<QSettings> settings = QQuickStyleAttached::settings(QStringLiteral("Universal"));
bool ok = false;
QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_THEME", settings, QStringLiteral("Theme"));
Theme themeEnum = toEnumValue<Theme>(themeValue, &ok);
if (ok)
- DefaultTheme = m_theme = qquickuniversal_effective_theme(themeEnum);
+ GlobalTheme = m_theme = qquickuniversal_effective_theme(themeEnum);
else if (!themeValue.isEmpty())
qWarning().nospace().noquote() << "Universal: unknown theme value: " << themeValue;
QByteArray accentValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_ACCENT", settings, QStringLiteral("Accent"));
Color accentEnum = toEnumValue<Color>(accentValue, &ok);
if (ok) {
- DefaultAccent = m_accent = qquickuniversal_accent_color(accentEnum);
+ GlobalAccent = m_accent = qquickuniversal_accent_color(accentEnum);
} else if (!accentValue.isEmpty()) {
QColor color(accentValue.constData());
if (color.isValid())
- DefaultAccent = m_accent = color.rgba();
+ GlobalAccent = m_accent = color.rgba();
else
qWarning().nospace().noquote() << "Universal: unknown accent value: " << accentValue;
}
@@ -558,28 +565,34 @@ void QQuickUniversalStyle::init()
QByteArray foregroundValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_FOREGROUND", settings, QStringLiteral("Foreground"));
Color foregroundEnum = toEnumValue<Color>(foregroundValue, &ok);
if (ok) {
- DefaultForeground = m_foreground = qquickuniversal_accent_color(foregroundEnum);
+ GlobalForeground = m_foreground = qquickuniversal_accent_color(foregroundEnum);
+ HasGlobalForeground = m_hasForeground = true;
} else if (!foregroundValue.isEmpty()) {
QColor color(foregroundValue.constData());
- if (color.isValid())
- DefaultForeground = m_foreground = color.rgba();
- else
+ if (color.isValid()) {
+ GlobalForeground = m_foreground = color.rgba();
+ HasGlobalForeground = m_hasForeground = true;
+ } else {
qWarning().nospace().noquote() << "Universal: unknown foreground value: " << foregroundValue;
+ }
}
QByteArray backgroundValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_BACKGROUND", settings, QStringLiteral("Background"));
Color backgroundEnum = toEnumValue<Color>(backgroundValue, &ok);
if (ok) {
- DefaultBackground = m_background = qquickuniversal_accent_color(backgroundEnum);
+ GlobalBackground = m_background = qquickuniversal_accent_color(backgroundEnum);
+ HasGlobalBackground = m_hasBackground = true;
} else if (!backgroundValue.isEmpty()) {
QColor color(backgroundValue.constData());
- if (color.isValid())
- DefaultBackground = m_background = color.rgba();
- else
+ if (color.isValid()) {
+ GlobalBackground = m_background = color.rgba();
+ HasGlobalBackground = m_hasBackground = true;
+ } else {
qWarning().nospace().noquote() << "Universal: unknown background value: " << backgroundValue;
+ }
}
- defaultsInitialized = true;
+ globalsInitialized = true;
}
QQuickStyleAttached::init(); // TODO: lazy init?
diff --git a/src/imports/controls/universal/qquickuniversalstyle_p.h b/src/imports/controls/universal/qquickuniversalstyle_p.h
index 19c346c8..0d3a6dab 100644
--- a/src/imports/controls/universal/qquickuniversalstyle_p.h
+++ b/src/imports/controls/universal/qquickuniversalstyle_p.h
@@ -214,12 +214,19 @@ private:
void init();
bool variantToRgba(const QVariant &var, const char *name, QRgb *rgba) const;
+ // These reflect whether a color value was explicitly set on the specific
+ // item that this attached style object represents.
bool m_explicitTheme;
bool m_explicitAccent;
bool m_explicitForeground;
bool m_explicitBackground;
+ // These will be true when this item has an explicit or inherited foreground/background
+ // color, or these colors were declared globally via settings (e.g. conf or env vars).
+ // Some color properties of the style will return different values depending on whether
+ // or not these are set.
bool m_hasForeground;
bool m_hasBackground;
+ // The actual values for this item, whether explicit, inherited or globally set.
QQuickUniversalStyle::Theme m_theme;
QRgb m_accent;
QRgb m_foreground;
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index fbc871f7..e2e6c84e 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -43,7 +43,6 @@
#include <QtQuick/private/qquickwindow_p.h>
#include <QtQuick/private/qquickanimation_p.h>
#include <QtQuick/private/qquicktransition_p.h>
-#include <QtQuick/private/qquickitemchangelistener_p.h>
QT_BEGIN_NAMESPACE
@@ -115,7 +114,7 @@ QT_BEGIN_NAMESPACE
\sa SwipeView, {Customizing Drawer}, {Navigation Controls}, {Popup Controls}
*/
-class QQuickDrawerPrivate : public QQuickPopupPrivate, public QQuickItemChangeListener
+class QQuickDrawerPrivate : public QQuickPopupPrivate
{
Q_DECLARE_PUBLIC(QQuickDrawer)
@@ -329,7 +328,7 @@ bool QQuickDrawerPrivate::handleMouseReleaseEvent(QQuickItem *item, QMouseEvent
static QList<QQuickStateAction> prepareTransition(QQuickDrawer *drawer, QQuickTransition *transition, qreal to)
{
QList<QQuickStateAction> actions;
- if (!transition)
+ if (!transition || !QQuickPopupPrivate::get(drawer)->window)
return actions;
qmlExecuteDeferred(transition);
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp
index ca18111c..b8522668 100644
--- a/src/quicktemplates2/qquickmenu.cpp
+++ b/src/quicktemplates2/qquickmenu.cpp
@@ -196,6 +196,7 @@ void QQuickMenuPrivate::itemSiblingOrderChanged(QQuickItem *)
void QQuickMenuPrivate::itemDestroyed(QQuickItem *item)
{
+ QQuickPopupPrivate::itemDestroyed(item);
int index = contentModel->indexOf(item, nullptr);
if (index != -1)
removeItem(index, item);
diff --git a/src/quicktemplates2/qquickmenu_p_p.h b/src/quicktemplates2/qquickmenu_p_p.h
index 4137112d..4ca3c379 100644
--- a/src/quicktemplates2/qquickmenu_p_p.h
+++ b/src/quicktemplates2/qquickmenu_p_p.h
@@ -50,7 +50,6 @@
#include <QtCore/qvector.h>
#include <QtCore/qpointer.h>
-#include <QtQuick/private/qquickitemchangelistener_p.h>
#include <QtQuickTemplates2/private/qquickpopup_p_p.h>
@@ -58,7 +57,7 @@ QT_BEGIN_NAMESPACE
class QQmlObjectModel;
-class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuPrivate : public QQuickPopupPrivate, public QQuickItemChangeListener
+class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuPrivate : public QQuickPopupPrivate
{
Q_DECLARE_PUBLIC(QQuickMenu)
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 14810c98..414ba782 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -115,8 +115,7 @@ static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPriv
| QQuickItemPrivate::Children;
static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry
- | QQuickItemPrivate::Parent
- | QQuickItemPrivate::Destroyed;
+ | QQuickItemPrivate::Parent;
QQuickPopupPrivate::QQuickPopupPrivate()
: QObjectPrivate()
@@ -551,14 +550,11 @@ void QQuickPopupPositioner::itemChildRemoved(QQuickItem *item, QQuickItem *child
removeAncestorListeners(item);
}
-void QQuickPopupPositioner::itemDestroyed(QQuickItem *item)
+void QQuickPopupPrivate::itemDestroyed(QQuickItem *item)
{
- Q_ASSERT(m_parentItem == item);
-
- m_parentItem = nullptr;
- m_popup->parentItem = nullptr;
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, ItemChangeTypes);
- removeAncestorListeners(item->parentItem());
+ Q_Q(QQuickPopup);
+ if (item == parentItem)
+ q->setParentItem(nullptr);
}
void QQuickPopupPrivate::reposition()
@@ -728,7 +724,10 @@ void QQuickPopupTransitionManager::transitionEnter()
state = Enter;
popup->prepareEnterTransition();
- transition(popup->enterActions, popup->enter, popup->q_func());
+ if (popup->window)
+ transition(popup->enterActions, popup->enter, popup->q_func());
+ else
+ finished();
}
void QQuickPopupTransitionManager::transitionExit()
@@ -738,7 +737,10 @@ void QQuickPopupTransitionManager::transitionExit()
state = Exit;
popup->prepareExitTransition();
- transition(popup->exitActions, popup->exit, popup->q_func());
+ if (popup->window)
+ transition(popup->exitActions, popup->exit, popup->q_func());
+ else
+ finished();
}
void QQuickPopupTransitionManager::finished()
@@ -768,8 +770,7 @@ QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent)
QQuickPopup::~QQuickPopup()
{
Q_D(QQuickPopup);
- d->setWindow(nullptr);
- d->positioner.setParentItem(nullptr);
+ setParentItem(nullptr);
delete d->popupItem;
}
@@ -1463,17 +1464,23 @@ void QQuickPopup::setParentItem(QQuickItem *parent)
if (d->parentItem == parent)
return;
- if (d->parentItem)
+ if (d->parentItem) {
QObjectPrivate::disconnect(d->parentItem, &QQuickItem::windowChanged, d, &QQuickPopupPrivate::setWindow);
+ QQuickItemPrivate::get(d->parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Destroyed);
+ }
d->parentItem = parent;
if (d->positioner.parentItem())
d->positioner.setParentItem(parent);
if (parent) {
QObjectPrivate::connect(parent, &QQuickItem::windowChanged, d, &QQuickPopupPrivate::setWindow);
+ QQuickItemPrivate::get(d->parentItem)->addItemChangeListener(d, QQuickItemPrivate::Destroyed);
+
QQuickControlPrivate *p = QQuickControlPrivate::get(d->popupItem);
p->resolveFont();
if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(parent->window()))
p->updateLocale(window->locale(), false); // explicit=false
+ } else {
+ close();
}
d->setWindow(parent ? parent->window() : nullptr);
emit parentChanged();
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index 342fecaf..4478c555 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -133,10 +133,9 @@ public:
void setParentItem(QQuickItem *parent);
protected:
- void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &);
- void itemParentChanged(QQuickItem *, QQuickItem *parent);
- void itemChildRemoved(QQuickItem *, QQuickItem *child);
- void itemDestroyed(QQuickItem *item);
+ void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
+ void itemParentChanged(QQuickItem *, QQuickItem *parent) override;
+ void itemChildRemoved(QQuickItem *, QQuickItem *child) override;
private:
void removeAncestorListeners(QQuickItem *item);
@@ -148,7 +147,7 @@ private:
QQuickPopupPrivate *m_popup;
};
-class QQuickPopupPrivate : public QObjectPrivate
+class QQuickPopupPrivate : public QObjectPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickPopup)
@@ -177,6 +176,7 @@ public:
void setBottomMargin(qreal value, bool reset = false);
void setWindow(QQuickWindow *window);
+ void itemDestroyed(QQuickItem *item) override;
bool focus;
bool modal;
diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp
index 6b51de95..e49d68a4 100644
--- a/src/quicktemplates2/qquicktooltip.cpp
+++ b/src/quicktemplates2/qquicktooltip.cpp
@@ -320,19 +320,27 @@ public:
QQuickToolTip *QQuickToolTipAttachedPrivate::instance(bool create) const
{
- static QPointer<QQuickToolTip> tip;
+ QQmlEngine *engine = qmlEngine(parent);
+ if (!engine)
+ return nullptr;
+
+ static const char *name = "_q_QQuickToolTip";
+
+ QQuickToolTip *tip = engine->property(name).value<QQuickToolTip *>();
if (!tip && create) {
// TODO: a cleaner way to create the instance? QQml(Meta)Type?
- QQmlContext *context = qmlContext(parent);
- if (context) {
- QQmlComponent component(context->engine());
- component.setData("import QtQuick.Controls 2.1; ToolTip { }", QUrl());
-
- QObject *object = component.create(context);
- tip = qobject_cast<QQuickToolTip *>(object);
- if (!tip)
- delete object;
- }
+ QQmlComponent component(engine);
+ component.setData("import QtQuick.Controls 2.1; ToolTip { }", QUrl());
+
+ QObject *object = component.create();
+ if (object)
+ object->setParent(engine);
+
+ tip = qobject_cast<QQuickToolTip *>(object);
+ if (!tip)
+ delete object;
+ else
+ engine->setProperty(name, QVariant::fromValue(object));
}
return tip;
}
@@ -366,8 +374,8 @@ void QQuickToolTipAttached::setText(const QString &text)
d->text = text;
emit textChanged();
- if (QQuickToolTip *tip = d->instance(true))
- tip->setText(text);
+ if (isVisible())
+ d->instance(true)->setText(text);
}
/*!
@@ -392,6 +400,9 @@ void QQuickToolTipAttached::setDelay(int delay)
d->delay = delay;
emit delayChanged();
+
+ if (isVisible())
+ d->instance(true)->setDelay(delay);
}
/*!
@@ -416,6 +427,9 @@ void QQuickToolTipAttached::setTimeout(int timeout)
d->timeout = timeout;
emit timeoutChanged();
+
+ if (isVisible())
+ d->instance(true)->setTimeout(timeout);
}
/*!
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 8272dbe7..4dabf06f 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -10,9 +10,11 @@ SUBDIRS += \
popup \
pressandhold \
qquickmaterialstyle \
+ qquickmaterialstyleconf \
qquickstyle \
qquickstyleselector \
qquickuniversalstyle \
+ qquickuniversalstyleconf \
revisions \
sanity \
snippets
diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml
index 7933bd9a..759d6988 100644
--- a/tests/auto/controls/data/tst_popup.qml
+++ b/tests/auto/controls/data/tst_popup.qml
@@ -987,13 +987,17 @@ TestCase {
control.destroy()
}
- // QTBUG-51989
function test_visible() {
var control = popupTemplate.createObject(testCase, {visible: true})
verify(control)
+ // QTBUG-51989
tryCompare(control, "visible", true)
+ // QTBUG-55347
+ control.parent = null
+ verify(!control.visible)
+
control.destroy()
}
diff --git a/tests/auto/controls/data/tst_tooltip.qml b/tests/auto/controls/data/tst_tooltip.qml
index a35798f0..1e6ecf01 100644
--- a/tests/auto/controls/data/tst_tooltip.qml
+++ b/tests/auto/controls/data/tst_tooltip.qml
@@ -118,6 +118,11 @@ TestCase {
var spy2 = signalSpy.createObject(item2, {target: item2.ToolTip, signalName: data.signalName})
verify(spy2.valid)
+ var sharedTip = ToolTip.toolTip
+ var sharedSpy = signalSpy.createObject(testCase, {target: sharedTip, signalName: data.signalName})
+ verify(sharedSpy.valid)
+
+ // change attached properties while the shared tooltip is not visible
item1.ToolTip[data.property] = data.setValue
compare(item1.ToolTip[data.property], data.setValue)
compare(spy1.count, 1)
@@ -125,6 +130,26 @@ TestCase {
compare(spy2.count, 0)
compare(item2.ToolTip[data.property], data.defaultValue)
+ // the shared tooltip is not visible for item1, so the attached
+ // property change should therefore not apply to the shared instance
+ compare(sharedSpy.count, 0)
+ compare(sharedTip[data.property], data.defaultValue)
+
+ // show the shared tooltip for item2
+ item2.ToolTip.visible = true
+ verify(item2.ToolTip.visible)
+ verify(sharedTip.visible)
+
+ // change attached properties while the shared tooltip is visible
+ item2.ToolTip[data.property] = data.setValue
+ compare(item2.ToolTip[data.property], data.setValue)
+ compare(spy2.count, 1)
+
+ // the shared tooltip is visible for item2, so the attached
+ // property change should apply to the shared instance
+ compare(sharedSpy.count, 1)
+ compare(sharedTip[data.property], data.setValue)
+
item1.destroy()
item2.destroy()
}
diff --git a/tests/auto/popup/tst_popup.cpp b/tests/auto/popup/tst_popup.cpp
index 7a8a6557..1166b517 100644
--- a/tests/auto/popup/tst_popup.cpp
+++ b/tests/auto/popup/tst_popup.cpp
@@ -61,6 +61,7 @@ private slots:
void activeFocusOnClose2();
void hover_data();
void hover();
+ void parentDestroyed();
};
void tst_popup::visible()
@@ -426,6 +427,14 @@ void tst_popup::hover()
QVERIFY(parentButton->isHovered());
}
+void tst_popup::parentDestroyed()
+{
+ QQuickPopup popup;
+ popup.setParentItem(new QQuickItem);
+ delete popup.parentItem();
+ QVERIFY(!popup.parentItem());
+}
+
QTEST_MAIN(tst_popup)
#include "tst_popup.moc"
diff --git a/tests/auto/qquickmaterialstyleconf/data/applicationwindow.qml b/tests/auto/qquickmaterialstyleconf/data/applicationwindow.qml
new file mode 100644
index 00000000..a1657a69
--- /dev/null
+++ b/tests/auto/qquickmaterialstyleconf/data/applicationwindow.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.7
+import QtQuick.Controls 2.0
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias label: label
+
+ Label {
+ id: label
+ }
+}
diff --git a/tests/auto/qquickmaterialstyleconf/qquickmaterialstyleconf.pro b/tests/auto/qquickmaterialstyleconf/qquickmaterialstyleconf.pro
new file mode 100644
index 00000000..fe8953e9
--- /dev/null
+++ b/tests/auto/qquickmaterialstyleconf/qquickmaterialstyleconf.pro
@@ -0,0 +1,17 @@
+CONFIG += testcase
+TARGET = tst_qquickmaterialstyleconf
+SOURCES += tst_qquickmaterialstyleconf.cpp
+
+macos:CONFIG -= app_bundle
+
+QT += core-private gui-private qml-private quick-private testlib quicktemplates2-private quickcontrols2-private
+
+include (../shared/util.pri)
+
+RESOURCES += qquickmaterialstyleconf.qrc
+
+TESTDATA = data/*
+
+OTHER_FILES += \
+ data/*
+
diff --git a/tests/auto/qquickmaterialstyleconf/qquickmaterialstyleconf.qrc b/tests/auto/qquickmaterialstyleconf/qquickmaterialstyleconf.qrc
new file mode 100644
index 00000000..53ba6450
--- /dev/null
+++ b/tests/auto/qquickmaterialstyleconf/qquickmaterialstyleconf.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>qtquickcontrols2.conf</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/qquickmaterialstyleconf/qtquickcontrols2.conf b/tests/auto/qquickmaterialstyleconf/qtquickcontrols2.conf
new file mode 100644
index 00000000..78634834
--- /dev/null
+++ b/tests/auto/qquickmaterialstyleconf/qtquickcontrols2.conf
@@ -0,0 +1,6 @@
+[Controls]
+Style=Material
+
+[Material]
+Background=#444444
+Foreground=Red
diff --git a/tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp b/tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp
new file mode 100644
index 00000000..c7670c21
--- /dev/null
+++ b/tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include "../shared/util.h"
+#include "../shared/visualtestutil.h"
+
+using namespace QQuickVisualTestUtil;
+
+class tst_qquickmaterialstyleconf : public QQmlDataTest
+{
+ Q_OBJECT
+
+public:
+
+private slots:
+ void conf();
+};
+
+void tst_qquickmaterialstyleconf::conf()
+{
+ QQuickApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
+
+ QQuickApplicationWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+ // We specified a custom background color, so the window should have it.
+ QCOMPARE(window->property("color").value<QColor>(), QColor("#444444"));
+
+ // We specified a custom foreground color, so the label should have it.
+ QQuickItem *label = window->property("label").value<QQuickItem*>();
+ QVERIFY(label);
+ QCOMPARE(label->property("color").value<QColor>(), QColor("#F44336"));
+}
+
+QTEST_MAIN(tst_qquickmaterialstyleconf)
+
+#include "tst_qquickmaterialstyleconf.moc"
diff --git a/tests/auto/qquickuniversalstyleconf/data/applicationwindow.qml b/tests/auto/qquickuniversalstyleconf/data/applicationwindow.qml
new file mode 100644
index 00000000..a1657a69
--- /dev/null
+++ b/tests/auto/qquickuniversalstyleconf/data/applicationwindow.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.7
+import QtQuick.Controls 2.0
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias label: label
+
+ Label {
+ id: label
+ }
+}
diff --git a/tests/auto/qquickuniversalstyleconf/qquickuniversalstyleconf.pro b/tests/auto/qquickuniversalstyleconf/qquickuniversalstyleconf.pro
new file mode 100644
index 00000000..9aaedbee
--- /dev/null
+++ b/tests/auto/qquickuniversalstyleconf/qquickuniversalstyleconf.pro
@@ -0,0 +1,17 @@
+CONFIG += testcase
+TARGET = tst_qquickuniversalstyleconf
+SOURCES += tst_qquickuniversalstyleconf.cpp
+
+macos:CONFIG -= app_bundle
+
+QT += core-private gui-private qml-private quick-private testlib quicktemplates2-private quickcontrols2-private
+
+include (../shared/util.pri)
+
+RESOURCES += qquickuniversalstyleconf.qrc
+
+TESTDATA = data/*
+
+OTHER_FILES += \
+ data/*
+
diff --git a/tests/auto/qquickuniversalstyleconf/qquickuniversalstyleconf.qrc b/tests/auto/qquickuniversalstyleconf/qquickuniversalstyleconf.qrc
new file mode 100644
index 00000000..53ba6450
--- /dev/null
+++ b/tests/auto/qquickuniversalstyleconf/qquickuniversalstyleconf.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>qtquickcontrols2.conf</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/qquickuniversalstyleconf/qtquickcontrols2.conf b/tests/auto/qquickuniversalstyleconf/qtquickcontrols2.conf
new file mode 100644
index 00000000..836372c9
--- /dev/null
+++ b/tests/auto/qquickuniversalstyleconf/qtquickcontrols2.conf
@@ -0,0 +1,6 @@
+[Controls]
+Style=Universal
+
+[Universal]
+Background=#444444
+Foreground=Red
diff --git a/tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp b/tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp
new file mode 100644
index 00000000..c676ae6d
--- /dev/null
+++ b/tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include "../shared/util.h"
+#include "../shared/visualtestutil.h"
+
+using namespace QQuickVisualTestUtil;
+
+class tst_qquickuniversalstyleconf : public QQmlDataTest
+{
+ Q_OBJECT
+
+public:
+
+private slots:
+ void conf();
+};
+
+void tst_qquickuniversalstyleconf::conf()
+{
+ QQuickApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
+
+ QQuickApplicationWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+ // We specified a custom background color, so the window should have it.
+ QCOMPARE(window->property("color").value<QColor>(), QColor("#444444"));
+
+ // We specified a custom foreground color, so the label should have it.
+ QQuickItem *label = window->property("label").value<QQuickItem*>();
+ QVERIFY(label);
+ QCOMPARE(label->property("color").value<QColor>(), QColor("#E51400"));
+}
+
+QTEST_MAIN(tst_qquickuniversalstyleconf)
+
+#include "tst_qquickuniversalstyleconf.moc"