Introduce the concept of an internal window system independent id

Summary:
For supporting Wayland windows in the kwin_rules_dialog we need a way to
pass a window id for Wayland windows to the dialog. This id needs to be
sent to the dbus interface to query window information just like the
interactive query. For Wayland windows we don't really have a window id
and it would require to also pass the windowing system to
kwin_rules_dialog and back through the dbus interface.

To not complicate things this change introduces a windowing system
independent id based on UUID. This could in future also be used
internally for areas where it's window id based and used in both
windowing systems.

Test Plan: Adjusted test cases to verify the uuid is generated and passed to Deleted

Reviewers: #kwin

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D16986
This commit is contained in:
Martin Flöser 2018-11-18 20:13:55 +01:00
parent f8459a71cc
commit 3ad9ac7229
4 changed files with 38 additions and 0 deletions

View file

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwin_wayland_test.h" #include "kwin_wayland_test.h"
#include "cursor.h" #include "cursor.h"
#include "effects.h" #include "effects.h"
#include "deleted.h"
#include "platform.h" #include "platform.h"
#include "shell_client.h" #include "shell_client.h"
#include "screens.h" #include "screens.h"
@ -95,6 +96,7 @@ private Q_SLOTS:
void TestShellClient::initTestCase() void TestShellClient::initTestCase()
{ {
qRegisterMetaType<KWin::Deleted*>();
qRegisterMetaType<KWin::ShellClient*>(); qRegisterMetaType<KWin::ShellClient*>();
qRegisterMetaType<KWin::AbstractClient*>(); qRegisterMetaType<KWin::AbstractClient*>();
qRegisterMetaType<KWayland::Client::Output*>(); qRegisterMetaType<KWayland::Client::Output*>();
@ -174,6 +176,12 @@ void TestShellClient::testMapUnmapMap()
QVERIFY(client->property("moveable").toBool()); QVERIFY(client->property("moveable").toBool());
QVERIFY(client->property("moveableAcrossScreens").toBool()); QVERIFY(client->property("moveableAcrossScreens").toBool());
QVERIFY(client->property("resizeable").toBool()); QVERIFY(client->property("resizeable").toBool());
QCOMPARE(client->internalId().isNull(), false);
const auto uuid = client->internalId();
QUuid deletedUuid;
QCOMPARE(deletedUuid.isNull(), true);
connect(client, &ShellClient::windowClosed, this, [&deletedUuid] (Toplevel *, Deleted *d) { deletedUuid = d->internalId(); });
// now unmap // now unmap
QSignalSpy hiddenSpy(client, &ShellClient::windowHidden); QSignalSpy hiddenSpy(client, &ShellClient::windowHidden);
@ -212,6 +220,7 @@ void TestShellClient::testMapUnmapMap()
QCOMPARE(hiddenSpy.count(), 2); QCOMPARE(hiddenSpy.count(), 2);
QCOMPARE(client->readyForPainting(), true); QCOMPARE(client->readyForPainting(), true);
QCOMPARE(client->isHiddenInternal(), true); QCOMPARE(client->isHiddenInternal(), true);
QCOMPARE(client->internalId(), uuid);
QVERIFY(windowClosedSpy.isEmpty()); QVERIFY(windowClosedSpy.isEmpty());
QCOMPARE(effectsWindowHiddenSpy.count(), 2); QCOMPARE(effectsWindowHiddenSpy.count(), 2);
QCOMPARE(effectsWindowHiddenSpy.last().first().value<EffectWindow*>(), client->effectWindow()); QCOMPARE(effectsWindowHiddenSpy.last().first().value<EffectWindow*>(), client->effectWindow());
@ -221,6 +230,8 @@ void TestShellClient::testMapUnmapMap()
QVERIFY(windowClosedSpy.wait()); QVERIFY(windowClosedSpy.wait());
QCOMPARE(windowClosedSpy.count(), 1); QCOMPARE(windowClosedSpy.count(), 1);
QCOMPARE(effectsWindowHiddenSpy.count(), 2); QCOMPARE(effectsWindowHiddenSpy.count(), 2);
QCOMPARE(deletedUuid.isNull(), false);
QCOMPARE(deletedUuid, uuid);
} }
void TestShellClient::testDesktopPresenceChanged() void TestShellClient::testDesktopPresenceChanged()

View file

@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "effects.h" #include "effects.h"
#include "effectloader.h" #include "effectloader.h"
#include "cursor.h" #include "cursor.h"
#include "deleted.h"
#include "platform.h" #include "platform.h"
#include "screens.h" #include "screens.h"
#include "shell_client.h" #include "shell_client.h"
@ -60,6 +61,7 @@ private Q_SLOTS:
void X11ClientTest::initTestCase() void X11ClientTest::initTestCase()
{ {
qRegisterMetaType<KWin::Deleted*>();
qRegisterMetaType<KWin::ShellClient*>(); qRegisterMetaType<KWin::ShellClient*>();
qRegisterMetaType<KWin::AbstractClient*>(); qRegisterMetaType<KWin::AbstractClient*>();
QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated);
@ -352,6 +354,13 @@ void X11ClientTest::testX11WindowId()
QCOMPARE(client->windowId(), w); QCOMPARE(client->windowId(), w);
QVERIFY(client->isActive()); QVERIFY(client->isActive());
QCOMPARE(client->window(), w); QCOMPARE(client->window(), w);
QCOMPARE(client->internalId().isNull(), false);
const auto uuid = client->internalId();
QUuid deletedUuid;
QCOMPARE(deletedUuid.isNull(), true);
connect(client, &Client::windowClosed, this, [&deletedUuid] (Toplevel *, Deleted *d) { deletedUuid = d->internalId(); });
NETRootInfo rootInfo(c.data(), NET::WMAllProperties); NETRootInfo rootInfo(c.data(), NET::WMAllProperties);
QCOMPARE(rootInfo.activeWindow(), client->window()); QCOMPARE(rootInfo.activeWindow(), client->window());
@ -379,6 +388,12 @@ void X11ClientTest::testX11WindowId()
// and destroy the window again // and destroy the window again
xcb_unmap_window(c.data(), w); xcb_unmap_window(c.data(), w);
xcb_flush(c.data()); xcb_flush(c.data());
QSignalSpy windowClosedSpy(client, &Client::windowClosed);
QVERIFY(windowClosedSpy.isValid());
QVERIFY(windowClosedSpy.wait());
QCOMPARE(deletedUuid.isNull(), false);
QCOMPARE(deletedUuid, uuid);
} }
void X11ClientTest::testCaptionChanges() void X11ClientTest::testCaptionChanges()

View file

@ -44,6 +44,7 @@ Toplevel::Toplevel()
, info(NULL) , info(NULL)
, ready_for_painting(true) , ready_for_painting(true)
, m_isDamaged(false) , m_isDamaged(false)
, m_internalId(QUuid::createUuid())
, m_client() , m_client()
, damage_handle(None) , damage_handle(None)
, is_shape(false) , is_shape(false)
@ -107,6 +108,7 @@ void Toplevel::detectShape(Window id)
// used only by Deleted::copy() // used only by Deleted::copy()
void Toplevel::copyToDeleted(Toplevel* c) void Toplevel::copyToDeleted(Toplevel* c)
{ {
m_internalId = c->internalId();
geom = c->geom; geom = c->geom;
m_visual = c->m_visual; m_visual = c->m_visual;
bit_depth = c->bit_depth; bit_depth = c->bit_depth;

View file

@ -31,6 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Qt // Qt
#include <QObject> #include <QObject>
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QUuid>
// xcb // xcb
#include <xcb/damage.h> #include <xcb/damage.h>
#include <xcb/xfixes.h> #include <xcb/xfixes.h>
@ -458,6 +459,14 @@ public:
**/ **/
virtual bool isPopupWindow() const; virtual bool isPopupWindow() const;
/**
* A UUID to uniquely identify this Toplevel independent of windowing system.
**/
QUuid internalId() const
{
return m_internalId;
}
Q_SIGNALS: Q_SIGNALS:
void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity); void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity);
void damaged(KWin::Toplevel* toplevel, const QRect& damage); void damaged(KWin::Toplevel* toplevel, const QRect& damage);
@ -577,6 +586,7 @@ protected:
private: private:
// when adding new data members, check also copyToDeleted() // when adding new data members, check also copyToDeleted()
QUuid m_internalId;
Xcb::Window m_client; Xcb::Window m_client;
xcb_damage_damage_t damage_handle; xcb_damage_damage_t damage_handle;
QRegion damage_region; // damage is really damaged window (XDamage) and texture needs QRegion damage_region; // damage is really damaged window (XDamage) and texture needs