Distinguish empty and non existent properties

This restores the behavior on KWin4: if I set an X property that doesn't have any data on a window, it's still information, so this makes the Xcb wrapper return an empty QByteArray that is not null.
EffectWindow::readProperty() now returns an empty QByteArray constructed the same way as it was in KWin4.

REVIEW:118645
BUG:335446
This commit is contained in:
Marco Martin 2014-06-11 11:08:02 +02:00
parent ea866906f0
commit 490e733590
2 changed files with 36 additions and 7 deletions

View file

@ -342,7 +342,26 @@ void TestXcbWrapper::testPropertyByteArray()
prop = Property(false, testWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 100000);
QCOMPARE(prop.toByteArray(), QByteArray());
QCOMPARE(prop.toByteArray(&ok), QByteArray());
//valid bytearray
QVERIFY(ok);
//The bytearray should be empty
QVERIFY(prop.toByteArray().isEmpty());
//The bytearray should be not null
QVERIFY(!prop.toByteArray().isNull());
QVERIFY(!prop.value<const char*>());
QCOMPARE(QByteArray(StringProperty(testWindow, XCB_ATOM_WM_NAME)), QByteArray());
// verify non existing property
Xcb::Atom invalid(QByteArrayLiteral("INVALID_ATOM"));
prop = Property(false, testWindow, invalid, XCB_ATOM_STRING, 0, 100000);
QCOMPARE(prop.toByteArray(), QByteArray());
QCOMPARE(prop.toByteArray(&ok), QByteArray());
//invalid bytearray
QVERIFY(!ok);
//The bytearray should be empty
QVERIFY(prop.toByteArray().isEmpty());
//The bytearray should be not null
QVERIFY(prop.toByteArray().isNull());
QVERIFY(!prop.value<const char*>());
QCOMPARE(QByteArray(StringProperty(testWindow, XCB_ATOM_WM_NAME)), QByteArray());
}

View file

@ -689,7 +689,8 @@ public:
* or @p type mismatch the @p defaultValue is returned. Also if the value length
* is @c 0 the @p defaultValue is returned. The optional argument @p ok is set
* to @c false in case of error and to @c true in case of successful reading of
* the property.
* the property. Ok will always be true if the property exists and has been
* successfully read, even in the case the property is empty and its length is 0
*
* @param format The expected format of the property value, e.g. 32 for XCB_ATOM_CARDINAL
* @param type The expected type of the property value, e.g. XCB_ATOM_CARDINAL
@ -712,12 +713,14 @@ public:
if (reply->format != format) {
return defaultValue;
}
if (xcb_get_property_value_length(reply) == 0) {
return defaultValue;
}
if (ok) {
*ok = true;
}
if (xcb_get_property_value_length(reply) == 0) {
return defaultValue;
}
return reinterpret_cast<T>(xcb_get_property_value(reply));
}
/**
@ -726,9 +729,16 @@ public:
* In case of error this method returns a null QByteArray.
**/
inline QByteArray toByteArray(uint8_t format = 8, xcb_atom_t type = XCB_ATOM_STRING, bool *ok = nullptr) {
const char *reply = value<const char*>(format, type, nullptr, ok);
if (!reply) {
return QByteArray();
bool valueOk = false;
const char *reply = value<const char*>(format, type, nullptr, &valueOk);
if (ok) {
*ok = valueOk;
}
if (valueOk && !reply) {
return QByteArray("", 0); // valid, not null, but empty data
} else if (!valueOk) {
return QByteArray(); // Property not found, data empty and null
}
return QByteArray(reply, xcb_get_property_value_length(data()));
}