Introduce an initial state event into Plasma Window protocol

Summary:
The event is sent to the client once all initial state is transmitted.
This means the client is able to see the PlasmaWindow completely created
and not in the intermediate state with further updates being pushed after
being created.

The client side API is adjusted to emit the windowCreated signal after
the initial state event is received. In addition if the window is already
unmapped, the signal will never be emitted which means the not valid
windows are not exposed to the client at all.

The tests are adjusted to reflect the new reality, which in most cases
just means removing the comment that this needs to be improved.

There is one kind of unrelated change included: when an empty icon is
set, the client side now creates a QIcon() instead of going through
QIcon::fromTheme. This wrong behavior was exposed now by the auto tests.

Reviewers: #plasma, hein

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D1773
This commit is contained in:
Martin Gräßlin 2016-06-06 12:39:51 +02:00
parent 076e8ba253
commit 2120d13632
3 changed files with 15 additions and 18 deletions

View file

@ -187,9 +187,6 @@ if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
m_display->dispatchEvents();
QSignalSpy dataChangedSpy(model, &PlasmaWindowModel::dataChanged);
VERIFY(dataChangedSpy.isValid());
// just creating sends one changed, this could be improved in the protocol
VERIFY(dataChangedSpy.wait());
dataChangedSpy.clear();
const QModelIndex index = model->index(0);
COMPARE(model->data(index, role).toBool(), false);
@ -454,9 +451,6 @@ void PlasmaWindowModelTest::testTitle()
m_display->dispatchEvents();
QSignalSpy dataChangedSpy(model, &PlasmaWindowModel::dataChanged);
QVERIFY(dataChangedSpy.isValid());
// just creating sends one changed, this could be improved in the protocol
QVERIFY(dataChangedSpy.wait());
dataChangedSpy.clear();
const QModelIndex index = model->index(0);
QCOMPARE(model->data(index, Qt::DisplayRole).toString(), QString());
@ -482,9 +476,6 @@ void PlasmaWindowModelTest::testAppId()
m_display->dispatchEvents();
QSignalSpy dataChangedSpy(model, &PlasmaWindowModel::dataChanged);
QVERIFY(dataChangedSpy.isValid());
// just creating sends one changed, this could be improved in the protocol
QVERIFY(dataChangedSpy.wait());
dataChangedSpy.clear();
const QModelIndex index = model->index(0);
QCOMPARE(model->data(index, PlasmaWindowModel::AppId).toString(), QString());
@ -510,9 +501,6 @@ void PlasmaWindowModelTest::testVirtualDesktop()
m_display->dispatchEvents();
QSignalSpy dataChangedSpy(model, &PlasmaWindowModel::dataChanged);
QVERIFY(dataChangedSpy.isValid());
// just creating sends one changed, this could be improved in the protocol
QVERIFY(dataChangedSpy.wait());
dataChangedSpy.clear();
const QModelIndex index = model->index(0);
QCOMPARE(model->data(index, PlasmaWindowModel::VirtualDesktop).toInt(), 0);

View file

@ -313,16 +313,16 @@ void TestWindowManagement::testDeleteActiveWindow()
void TestWindowManagement::testCreateAfterUnmap()
{
// this test verifies that we don't get a protocol error on client side when creating an already unmapped window.
QSignalSpy windowSpy(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::windowCreated);
QVERIFY(windowSpy.isValid());
QCOMPARE(m_windowManagement->children().count(), 1);
// create and unmap in one go
// client will first handle the create, the unmap will be sent once the server side is bound
auto serverWindow = m_windowManagementInterface->createWindow(this);
serverWindow->unmap();
QCOMPARE(m_windowManagementInterface->children().count(), 0);
QVERIFY(windowSpy.wait());
QCOMPARE(windowSpy.count(), 1);
auto window = windowSpy.first().first().value<KWayland::Client::PlasmaWindow*>();
QCoreApplication::instance()->processEvents();
QCoreApplication::instance()->processEvents(QEventLoop::WaitForMoreEvents);
QTRY_COMPARE(m_windowManagement->children().count(), 2);
auto window = dynamic_cast<KWayland::Client::PlasmaWindow*>(m_windowManagement->children().last());
QVERIFY(window);
// now this is not yet on the server, on the server it will be after next roundtrip
// which we can trigger by waiting for destroy of the newly created window.
@ -330,6 +330,7 @@ void TestWindowManagement::testCreateAfterUnmap()
QSignalSpy clientDestroyedSpy(window, &QObject::destroyed);
QVERIFY(clientDestroyedSpy.isValid());
QVERIFY(clientDestroyedSpy.wait());
QCOMPARE(m_windowManagement->children().count(), 1);
// the server side created a helper PlasmaWindowInterface with PlasmaWindowManagementInterface as parent
// it emitted unmapped so we can be sure it will be destroyed directly
QCOMPARE(m_windowManagementInterface->children().count(), 1);

View file

@ -171,8 +171,8 @@ void PlasmaWindowManagementInterface::Private::getWindowCallback(wl_client *clie
if (it == p->windows.constEnd()) {
// create a temp window just for the resource and directly send an unmapped
PlasmaWindowInterface *window = new PlasmaWindowInterface(p->q, p->q);
window->d->unmapped = true;
window->d->createResource(resource, id);
window->unmap();
return;
}
(*it)->d->createResource(resource, id);
@ -320,6 +320,14 @@ void PlasmaWindowInterface::Private::createResource(wl_resource *parent, uint32_
}
org_kde_plasma_window_send_state_changed(resource, m_state);
org_kde_plasma_window_send_themed_icon_name_changed(resource, m_themedIconName.toUtf8().constData());
if (unmapped) {
org_kde_plasma_window_send_unmapped(resource);
}
if (wl_resource_get_version(resource) >= ORG_KDE_PLASMA_WINDOW_INITIAL_STATE_SINCE_VERSION) {
org_kde_plasma_window_send_initial_state(resource);
}
c->flush();
}