Advance Wayland and KDE package bring-up
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,859 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "nettesthelper.h"
|
||||
#include <netwm.h>
|
||||
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <qtest_widgets.h>
|
||||
|
||||
// system
|
||||
#include <unistd.h>
|
||||
|
||||
using Property = UniqueCPointer<xcb_get_property_reply_t>;
|
||||
|
||||
Q_DECLARE_METATYPE(NET::Orientation)
|
||||
Q_DECLARE_METATYPE(NET::DesktopLayoutCorner)
|
||||
|
||||
static const char *s_wmName = "netrootinfotest";
|
||||
|
||||
class NetRootInfoTestWM : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
void testCtor();
|
||||
void testSupported();
|
||||
void testClientList();
|
||||
void testClientListStacking();
|
||||
void testNumberOfDesktops();
|
||||
void testCurrentDesktop();
|
||||
void testDesktopNames();
|
||||
void testDesktopLayout_data();
|
||||
void testDesktopLayout();
|
||||
void testDesktopGeometry();
|
||||
void testDesktopViewports();
|
||||
void testShowingDesktop_data();
|
||||
void testShowingDesktop();
|
||||
void testWorkArea();
|
||||
void testActiveWindow();
|
||||
void testVirtualRoots();
|
||||
void testDontCrashMapViewports();
|
||||
|
||||
private:
|
||||
void waitForPropertyChange(NETRootInfo *info, xcb_atom_t atom, NET::Property prop, NET::Property2 prop2 = NET::Property2(0));
|
||||
xcb_connection_t *connection()
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
xcb_connection_t *m_connection;
|
||||
QList<xcb_connection_t *> m_connections;
|
||||
std::unique_ptr<QProcess> m_xvfb;
|
||||
xcb_window_t m_supportWindow;
|
||||
xcb_window_t m_rootWindow;
|
||||
};
|
||||
|
||||
void NetRootInfoTestWM::cleanupTestCase()
|
||||
{
|
||||
while (!m_connections.isEmpty()) {
|
||||
xcb_disconnect(m_connections.takeFirst());
|
||||
}
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::init()
|
||||
{
|
||||
// first reset just to be sure
|
||||
m_connection = nullptr;
|
||||
m_supportWindow = XCB_WINDOW_NONE;
|
||||
// start Xvfb
|
||||
const QString xfvbExec = QStandardPaths::findExecutable(QStringLiteral("Xvfb"));
|
||||
QVERIFY(!xfvbExec.isEmpty());
|
||||
|
||||
m_xvfb.reset(new QProcess);
|
||||
// use pipe to pass fd to Xvfb to get back the display id
|
||||
int pipeFds[2];
|
||||
QVERIFY(pipe(pipeFds) == 0);
|
||||
m_xvfb->start(xfvbExec, QStringList{QStringLiteral("-displayfd"), QString::number(pipeFds[1])});
|
||||
QVERIFY(m_xvfb->waitForStarted());
|
||||
QCOMPARE(m_xvfb->state(), QProcess::Running);
|
||||
|
||||
// reads from pipe, closes write side
|
||||
close(pipeFds[1]);
|
||||
|
||||
QFile readPipe;
|
||||
QVERIFY(readPipe.open(pipeFds[0], QIODevice::ReadOnly, QFileDevice::AutoCloseHandle));
|
||||
QByteArray displayNumber = readPipe.readLine();
|
||||
readPipe.close();
|
||||
|
||||
displayNumber.prepend(QByteArray(":"));
|
||||
displayNumber.remove(displayNumber.size() - 1, 1);
|
||||
|
||||
// create X connection
|
||||
int screen = 0;
|
||||
m_connection = xcb_connect(displayNumber.constData(), &screen);
|
||||
QVERIFY(m_connection);
|
||||
QVERIFY(!xcb_connection_has_error(m_connection));
|
||||
m_rootWindow = KXUtils::rootWindow(m_connection, screen);
|
||||
uint32_t values[] = {XCB_EVENT_MASK_PROPERTY_CHANGE};
|
||||
xcb_change_window_attributes(m_connection, m_rootWindow, XCB_CW_EVENT_MASK, values);
|
||||
|
||||
// create support window
|
||||
values[0] = true;
|
||||
m_supportWindow = xcb_generate_id(m_connection);
|
||||
xcb_create_window(m_connection,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
m_supportWindow,
|
||||
m_rootWindow,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
XCB_CW_OVERRIDE_REDIRECT,
|
||||
values);
|
||||
const uint32_t lowerValues[] = {XCB_STACK_MODE_BELOW};
|
||||
// we need to do the lower window with a roundtrip, otherwise NETRootInfo is not functioning
|
||||
UniqueCPointer<xcb_generic_error_t> error(
|
||||
xcb_request_check(m_connection, xcb_configure_window_checked(m_connection, m_supportWindow, XCB_CONFIG_WINDOW_STACK_MODE, lowerValues)));
|
||||
QVERIFY(!error);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::cleanup()
|
||||
{
|
||||
// destroy support window
|
||||
xcb_destroy_window(connection(), m_supportWindow);
|
||||
m_supportWindow = XCB_WINDOW_NONE;
|
||||
|
||||
// close connection
|
||||
// delay till clenupTestCase as otherwise xcb reuses the same memory address
|
||||
m_connections << connection();
|
||||
// kill Xvfb
|
||||
m_xvfb->terminate();
|
||||
m_xvfb->waitForFinished();
|
||||
m_xvfb.reset();
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::waitForPropertyChange(NETRootInfo *info, xcb_atom_t atom, NET::Property prop, NET::Property2 prop2)
|
||||
{
|
||||
while (true) {
|
||||
UniqueCPointer<xcb_generic_event_t> event(xcb_wait_for_event(connection()));
|
||||
if (!event) {
|
||||
break;
|
||||
}
|
||||
if ((event->response_type & ~0x80) != XCB_PROPERTY_NOTIFY) {
|
||||
continue;
|
||||
}
|
||||
xcb_property_notify_event_t *pe = reinterpret_cast<xcb_property_notify_event_t *>(event.get());
|
||||
if (pe->window != m_rootWindow) {
|
||||
continue;
|
||||
}
|
||||
if (pe->atom != atom) {
|
||||
continue;
|
||||
}
|
||||
NET::Properties dirty;
|
||||
NET::Properties2 dirty2;
|
||||
info->event(event.get(), &dirty, &dirty2);
|
||||
if (prop != 0) {
|
||||
QVERIFY(dirty & prop);
|
||||
}
|
||||
if (prop2 != 0) {
|
||||
QVERIFY(dirty2 & prop2);
|
||||
}
|
||||
if (!prop) {
|
||||
QCOMPARE(dirty, NET::Properties());
|
||||
}
|
||||
if (!prop2) {
|
||||
QCOMPARE(dirty2, NET::Properties2());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testCtor()
|
||||
{
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.xcbConnection(), connection());
|
||||
QCOMPARE(rootInfo.rootWindow(), m_rootWindow);
|
||||
QCOMPARE(rootInfo.supportWindow(), m_supportWindow);
|
||||
QCOMPARE(rootInfo.wmName(), s_wmName);
|
||||
QCOMPARE(rootInfo.supportedProperties(), NET::WMAllProperties);
|
||||
QCOMPARE(rootInfo.supportedProperties2(), NET::WM2AllProperties);
|
||||
QCOMPARE(rootInfo.supportedActions(), NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.supportedStates(), NET::States(~0u));
|
||||
QCOMPARE(rootInfo.supportedWindowTypes(), NET::AllTypesMask);
|
||||
|
||||
QCOMPARE(rootInfo.passedProperties(), NET::WMAllProperties);
|
||||
QCOMPARE(rootInfo.passedProperties2(), NET::WM2AllProperties);
|
||||
QCOMPARE(rootInfo.passedActions(), NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.passedStates(), NET::States(~0u));
|
||||
QCOMPARE(rootInfo.passedWindowTypes(), NET::AllTypesMask);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testSupported()
|
||||
{
|
||||
KXUtils::Atom supported(connection(), QByteArrayLiteral("_NET_SUPPORTED"));
|
||||
KXUtils::Atom wmCheck(connection(), QByteArrayLiteral("_NET_SUPPORTING_WM_CHECK"));
|
||||
KXUtils::Atom wmName(connection(), QByteArrayLiteral("_NET_WM_NAME"));
|
||||
KXUtils::Atom utf8String(connection(), QByteArrayLiteral("UTF8_STRING"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
int count = 0;
|
||||
for (int i = 0; i < 34; ++i) {
|
||||
if (i == 12) {
|
||||
continue;
|
||||
}
|
||||
QVERIFY(rootInfo.isSupported(NET::Property(1 << i)));
|
||||
count++;
|
||||
}
|
||||
for (int i = 0; i < 22; ++i) {
|
||||
QVERIFY(rootInfo.isSupported(NET::Property2(1 << i)));
|
||||
count++;
|
||||
}
|
||||
|
||||
QVERIFY(rootInfo.isSupported(NET::WM2GTKShowWindowMenu));
|
||||
count++;
|
||||
|
||||
for (int i = 0; i < 17; ++i) {
|
||||
QVERIFY(rootInfo.isSupported(NET::WindowTypeMask(1 << i)));
|
||||
count++;
|
||||
}
|
||||
for (int i = 0; i < 13; ++i) {
|
||||
QVERIFY(rootInfo.isSupported(NET::State(1 << i)));
|
||||
count++;
|
||||
}
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
QVERIFY(rootInfo.isSupported(NET::Action(1 << i)));
|
||||
count++;
|
||||
}
|
||||
// NET::WMFrameExtents has two properties
|
||||
count += 1;
|
||||
// XAWState, WMGeometry, WM2TransientFor, WM2GroupLeader, WM2WindowClass, WM2WindowRole, WM2ClientMachine
|
||||
count -= 7;
|
||||
// WM2BlockCompositing has 3 properties
|
||||
count += 2;
|
||||
// Add _GTK_FRAME_EXTENTS
|
||||
++count;
|
||||
|
||||
QVERIFY(supported != XCB_ATOM_NONE);
|
||||
QVERIFY(utf8String != XCB_ATOM_NONE);
|
||||
QVERIFY(wmCheck != XCB_ATOM_NONE);
|
||||
QVERIFY(wmName != XCB_ATOM_NONE);
|
||||
|
||||
// we should have got some events
|
||||
waitForPropertyChange(&rootInfo, supported, NET::Supported);
|
||||
waitForPropertyChange(&rootInfo, wmCheck, NET::SupportingWMCheck);
|
||||
|
||||
// get the cookies of the things to check
|
||||
xcb_get_property_cookie_t supportedCookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), supported, XCB_ATOM_ATOM, 0, 101);
|
||||
xcb_get_property_cookie_t wmCheckRootCookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), wmCheck, XCB_ATOM_WINDOW, 0, 1);
|
||||
xcb_get_property_cookie_t wmCheckSupportWinCookie = xcb_get_property_unchecked(connection(), false, m_supportWindow, wmCheck, XCB_ATOM_WINDOW, 0, 1);
|
||||
xcb_get_property_cookie_t wmNameCookie = xcb_get_property_unchecked(connection(), false, m_supportWindow, wmName, utf8String, 0, 16);
|
||||
|
||||
Property supportedReply(xcb_get_property_reply(connection(), supportedCookie, nullptr));
|
||||
QVERIFY(supportedReply);
|
||||
QCOMPARE(supportedReply->format, uint8_t(32));
|
||||
QCOMPARE(supportedReply->value_len, uint32_t(count));
|
||||
// TODO: check that the correct atoms are set?
|
||||
Property wmCheckRootReply(xcb_get_property_reply(connection(), wmCheckRootCookie, nullptr));
|
||||
QVERIFY(wmCheckRootReply);
|
||||
QCOMPARE(wmCheckRootReply->format, uint8_t(32));
|
||||
QCOMPARE(wmCheckRootReply->value_len, uint32_t(1));
|
||||
QCOMPARE(reinterpret_cast<xcb_window_t *>(xcb_get_property_value(wmCheckRootReply.get()))[0], m_supportWindow);
|
||||
|
||||
Property wmCheckSupportReply(xcb_get_property_reply(connection(), wmCheckSupportWinCookie, nullptr));
|
||||
QVERIFY(wmCheckSupportReply);
|
||||
QCOMPARE(wmCheckSupportReply->format, uint8_t(32));
|
||||
QCOMPARE(wmCheckSupportReply->value_len, uint32_t(1));
|
||||
QCOMPARE(reinterpret_cast<xcb_window_t *>(xcb_get_property_value(wmCheckSupportReply.get()))[0], m_supportWindow);
|
||||
|
||||
Property wmNameReply(xcb_get_property_reply(connection(), wmNameCookie, nullptr));
|
||||
QVERIFY(wmNameReply);
|
||||
QCOMPARE(wmNameReply->format, uint8_t(8));
|
||||
QCOMPARE(wmNameReply->value_len, uint32_t(15));
|
||||
QCOMPARE(reinterpret_cast<const char *>(xcb_get_property_value(wmNameReply.get())), s_wmName);
|
||||
|
||||
// disable some supported
|
||||
rootInfo.setSupported(NET::WMFrameExtents, false);
|
||||
rootInfo.setSupported(NET::WM2KDETemporaryRules, false);
|
||||
rootInfo.setSupported(NET::ActionChangeDesktop, false);
|
||||
rootInfo.setSupported(NET::FullScreen, false);
|
||||
QVERIFY(rootInfo.isSupported(NET::ToolbarMask));
|
||||
QVERIFY(rootInfo.isSupported(NET::OnScreenDisplayMask));
|
||||
QVERIFY(rootInfo.isSupported(NET::DockMask));
|
||||
rootInfo.setSupported(NET::ToolbarMask, false);
|
||||
rootInfo.setSupported(NET::OnScreenDisplayMask, false);
|
||||
|
||||
QVERIFY(!rootInfo.isSupported(NET::WMFrameExtents));
|
||||
QVERIFY(!rootInfo.isSupported(NET::WM2KDETemporaryRules));
|
||||
QVERIFY(!rootInfo.isSupported(NET::ActionChangeDesktop));
|
||||
QVERIFY(!rootInfo.isSupported(NET::FullScreen));
|
||||
QVERIFY(!rootInfo.isSupported(NET::ToolbarMask));
|
||||
QVERIFY(!rootInfo.isSupported(NET::OnScreenDisplayMask));
|
||||
QVERIFY(rootInfo.isSupported(NET::DockMask));
|
||||
|
||||
// lets get supported again
|
||||
supportedCookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), supported, XCB_ATOM_ATOM, 0, 90);
|
||||
supportedReply.reset(xcb_get_property_reply(connection(), supportedCookie, nullptr));
|
||||
QVERIFY(supportedReply);
|
||||
QCOMPARE(supportedReply->format, uint8_t(32));
|
||||
QCOMPARE(supportedReply->value_len, uint32_t(count - 7));
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
// we should have got some events
|
||||
waitForPropertyChange(&rootInfo, supported, NET::Supported);
|
||||
waitForPropertyChange(&rootInfo, wmCheck, NET::SupportingWMCheck);
|
||||
}
|
||||
|
||||
// turn something off, just to get another event
|
||||
rootInfo.setSupported(NET::WM2BlockCompositing, false);
|
||||
// lets get supported again
|
||||
supportedCookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), supported, XCB_ATOM_ATOM, 0, 90);
|
||||
supportedReply.reset(xcb_get_property_reply(connection(), supportedCookie, nullptr));
|
||||
QVERIFY(supportedReply);
|
||||
QCOMPARE(supportedReply->format, uint8_t(32));
|
||||
QCOMPARE(supportedReply->value_len, uint32_t(count - 9));
|
||||
NETRootInfo clientInfo(connection(), NET::Supported | NET::SupportingWMCheck);
|
||||
waitForPropertyChange(&clientInfo, supported, NET::Supported);
|
||||
waitForPropertyChange(&clientInfo, wmCheck, NET::SupportingWMCheck);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testClientList()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_CLIENT_LIST"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.clientListCount(), 0);
|
||||
QVERIFY(!rootInfo.clientList());
|
||||
|
||||
xcb_window_t windows[] = {xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection())};
|
||||
rootInfo.setClientList(windows, 5);
|
||||
QCOMPARE(rootInfo.clientListCount(), 5);
|
||||
const xcb_window_t *otherWins = rootInfo.clientList();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(otherWins[i], windows[i]);
|
||||
}
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_WINDOW, 0, 5);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(5));
|
||||
const xcb_window_t *propWins = reinterpret_cast<xcb_window_t *>(xcb_get_property_value(reply.get()));
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(propWins[i], windows[i]);
|
||||
}
|
||||
|
||||
// wait for our property
|
||||
NETRootInfo clientInfo(connection(), NET::Supported | NET::SupportingWMCheck | NET::ClientList);
|
||||
waitForPropertyChange(&clientInfo, atom, NET::ClientList);
|
||||
QCOMPARE(clientInfo.clientListCount(), 5);
|
||||
const xcb_window_t *otherWins2 = clientInfo.clientList();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(otherWins2[i], windows[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testClientListStacking()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_CLIENT_LIST_STACKING"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.clientListStackingCount(), 0);
|
||||
QVERIFY(!rootInfo.clientListStacking());
|
||||
|
||||
xcb_window_t windows[] = {xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection())};
|
||||
rootInfo.setClientListStacking(windows, 5);
|
||||
QCOMPARE(rootInfo.clientListStackingCount(), 5);
|
||||
const xcb_window_t *otherWins = rootInfo.clientListStacking();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(otherWins[i], windows[i]);
|
||||
}
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_WINDOW, 0, 5);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(5));
|
||||
const xcb_window_t *propWins = reinterpret_cast<xcb_window_t *>(xcb_get_property_value(reply.get()));
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(propWins[i], windows[i]);
|
||||
}
|
||||
|
||||
// wait for our property
|
||||
waitForPropertyChange(&rootInfo, atom, NET::ClientListStacking);
|
||||
QCOMPARE(rootInfo.clientListStackingCount(), 5);
|
||||
const xcb_window_t *otherWins2 = rootInfo.clientListStacking();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(otherWins2[i], windows[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testVirtualRoots()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_VIRTUAL_ROOTS"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.virtualRootsCount(), 0);
|
||||
QVERIFY(!rootInfo.virtualRoots());
|
||||
|
||||
xcb_window_t windows[] = {xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection()),
|
||||
xcb_generate_id(connection())};
|
||||
rootInfo.setVirtualRoots(windows, 5);
|
||||
QCOMPARE(rootInfo.virtualRootsCount(), 5);
|
||||
const xcb_window_t *otherWins = rootInfo.virtualRoots();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(otherWins[i], windows[i]);
|
||||
}
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_WINDOW, 0, 5);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(5));
|
||||
const xcb_window_t *propWins = reinterpret_cast<xcb_window_t *>(xcb_get_property_value(reply.get()));
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(propWins[i], windows[i]);
|
||||
}
|
||||
|
||||
// wait for our property - reported to a Client NETRootInfo
|
||||
NETRootInfo clientInfo(connection(), NET::VirtualRoots);
|
||||
waitForPropertyChange(&clientInfo, atom, NET::VirtualRoots);
|
||||
QCOMPARE(rootInfo.virtualRootsCount(), 5);
|
||||
const xcb_window_t *otherWins2 = rootInfo.virtualRoots();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QCOMPARE(otherWins2[i], windows[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testNumberOfDesktops()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_NUMBER_OF_DESKTOPS"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.numberOfDesktops(), 1);
|
||||
rootInfo.setNumberOfDesktops(4);
|
||||
QCOMPARE(rootInfo.numberOfDesktops(), 4);
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_CARDINAL, 0, 1);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(1));
|
||||
QCOMPARE(reinterpret_cast<uint32_t *>(xcb_get_property_value(reply.get()))[0], uint32_t(4));
|
||||
|
||||
// wait for our property
|
||||
waitForPropertyChange(&rootInfo, atom, NET::NumberOfDesktops);
|
||||
QCOMPARE(rootInfo.numberOfDesktops(), 4);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testCurrentDesktop()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_CURRENT_DESKTOP"));
|
||||
// TODO: verify that current desktop cannot be higher than number of desktops
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.currentDesktop(), 1);
|
||||
rootInfo.setCurrentDesktop(5);
|
||||
QCOMPARE(rootInfo.currentDesktop(), 5);
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_CARDINAL, 0, 1);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(1));
|
||||
// note: API starts counting at 1, but property starts counting at 5, because of that subtracting one
|
||||
QCOMPARE(reinterpret_cast<uint32_t *>(xcb_get_property_value(reply.get()))[0], uint32_t(5 - 1));
|
||||
|
||||
// wait for our property
|
||||
waitForPropertyChange(&rootInfo, atom, NET::CurrentDesktop);
|
||||
QCOMPARE(rootInfo.currentDesktop(), 5);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testDesktopNames()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_DESKTOP_NAMES"));
|
||||
KXUtils::Atom utf8String(connection(), QByteArrayLiteral("UTF8_STRING"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QVERIFY(!rootInfo.desktopName(0));
|
||||
QVERIFY(!rootInfo.desktopName(1));
|
||||
QVERIFY(!rootInfo.desktopName(2));
|
||||
rootInfo.setDesktopName(1, "foo");
|
||||
rootInfo.setDesktopName(2, "bar");
|
||||
rootInfo.setNumberOfDesktops(2);
|
||||
QCOMPARE(rootInfo.desktopName(1), "foo");
|
||||
QCOMPARE(rootInfo.desktopName(2), "bar");
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
QVERIFY(utf8String != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, utf8String, 0, 10000);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(8));
|
||||
QCOMPARE(reply->value_len, uint32_t(8));
|
||||
QCOMPARE(reinterpret_cast<const char *>(xcb_get_property_value(reply.get())), "foo\0bar");
|
||||
|
||||
// wait for our property
|
||||
waitForPropertyChange(&rootInfo, atom, NET::DesktopNames);
|
||||
QCOMPARE(rootInfo.desktopName(1), "foo");
|
||||
QCOMPARE(rootInfo.desktopName(2), "bar");
|
||||
// there should be two events
|
||||
waitForPropertyChange(&rootInfo, atom, NET::DesktopNames);
|
||||
QCOMPARE(rootInfo.desktopName(1), "foo");
|
||||
QCOMPARE(rootInfo.desktopName(2), "bar");
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testActiveWindow()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_ACTIVE_WINDOW"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QVERIFY(rootInfo.activeWindow() == XCB_WINDOW_NONE);
|
||||
// rootinfo doesn't verify whether our window is a window, so we just generate an ID
|
||||
xcb_window_t activeWindow = xcb_generate_id(connection());
|
||||
rootInfo.setActiveWindow(activeWindow);
|
||||
QCOMPARE(rootInfo.activeWindow(), activeWindow);
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_WINDOW, 0, 1);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(1));
|
||||
QCOMPARE(reinterpret_cast<xcb_window_t *>(xcb_get_property_value(reply.get()))[0], activeWindow);
|
||||
|
||||
// wait for our property
|
||||
waitForPropertyChange(&rootInfo, atom, NET::ActiveWindow);
|
||||
QCOMPARE(rootInfo.activeWindow(), activeWindow);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testDesktopGeometry()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_DESKTOP_GEOMETRY"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QCOMPARE(rootInfo.desktopGeometry().width, 0);
|
||||
QCOMPARE(rootInfo.desktopGeometry().height, 0);
|
||||
|
||||
NETSize size;
|
||||
size.width = 1000;
|
||||
size.height = 800;
|
||||
rootInfo.setDesktopGeometry(size);
|
||||
QCOMPARE(rootInfo.desktopGeometry().width, size.width);
|
||||
QCOMPARE(rootInfo.desktopGeometry().height, size.height);
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_CARDINAL, 0, 2);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(2));
|
||||
uint32_t *data = reinterpret_cast<uint32_t *>(xcb_get_property_value(reply.get()));
|
||||
QCOMPARE(data[0], uint32_t(size.width));
|
||||
QCOMPARE(data[1], uint32_t(size.height));
|
||||
|
||||
// wait for our property
|
||||
waitForPropertyChange(&rootInfo, atom, NET::DesktopGeometry);
|
||||
QCOMPARE(rootInfo.desktopGeometry().width, size.width);
|
||||
QCOMPARE(rootInfo.desktopGeometry().height, size.height);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testDesktopLayout_data()
|
||||
{
|
||||
QTest::addColumn<NET::Orientation>("orientation");
|
||||
QTest::addColumn<QSize>("columnsRows");
|
||||
QTest::addColumn<NET::DesktopLayoutCorner>("corner");
|
||||
|
||||
QTest::newRow("h/1/1/tl") << NET::OrientationHorizontal << QSize(1, 1) << NET::DesktopLayoutCornerTopLeft;
|
||||
QTest::newRow("h/1/0/tr") << NET::OrientationHorizontal << QSize(1, 0) << NET::DesktopLayoutCornerTopRight;
|
||||
QTest::newRow("h/0/1/bl") << NET::OrientationHorizontal << QSize(0, 1) << NET::DesktopLayoutCornerBottomLeft;
|
||||
QTest::newRow("h/1/2/br") << NET::OrientationHorizontal << QSize(1, 2) << NET::DesktopLayoutCornerBottomRight;
|
||||
QTest::newRow("v/3/2/tl") << NET::OrientationVertical << QSize(3, 2) << NET::DesktopLayoutCornerTopLeft;
|
||||
QTest::newRow("v/5/4/tr") << NET::OrientationVertical << QSize(5, 4) << NET::DesktopLayoutCornerTopRight;
|
||||
QTest::newRow("v/2/1/bl") << NET::OrientationVertical << QSize(2, 1) << NET::DesktopLayoutCornerBottomLeft;
|
||||
QTest::newRow("v/3/2/br") << NET::OrientationVertical << QSize(3, 2) << NET::DesktopLayoutCornerBottomRight;
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testDesktopLayout()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_DESKTOP_LAYOUT"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QFETCH(NET::Orientation, orientation);
|
||||
QFETCH(QSize, columnsRows);
|
||||
QFETCH(NET::DesktopLayoutCorner, corner);
|
||||
|
||||
rootInfo.setDesktopLayout(orientation, columnsRows.width(), columnsRows.height(), corner);
|
||||
QCOMPARE(rootInfo.desktopLayoutOrientation(), orientation);
|
||||
QCOMPARE(rootInfo.desktopLayoutColumnsRows(), columnsRows);
|
||||
QCOMPARE(rootInfo.desktopLayoutCorner(), corner);
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_CARDINAL, 0, 4);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(4));
|
||||
uint32_t *data = reinterpret_cast<uint32_t *>(xcb_get_property_value(reply.get()));
|
||||
QCOMPARE(data[0], uint32_t(orientation));
|
||||
QCOMPARE(data[1], uint32_t(columnsRows.width()));
|
||||
QCOMPARE(data[2], uint32_t(columnsRows.height()));
|
||||
QCOMPARE(data[3], uint32_t(corner));
|
||||
|
||||
// wait for our property
|
||||
waitForPropertyChange(&rootInfo, atom, NET::Property(0), NET::WM2DesktopLayout);
|
||||
QCOMPARE(rootInfo.desktopLayoutOrientation(), orientation);
|
||||
QCOMPARE(rootInfo.desktopLayoutColumnsRows(), columnsRows);
|
||||
QCOMPARE(rootInfo.desktopLayoutCorner(), corner);
|
||||
|
||||
NETRootInfo info2(connection(), NET::WMAllProperties, NET::WM2AllProperties);
|
||||
QCOMPARE(info2.desktopLayoutColumnsRows(), columnsRows);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testDesktopViewports()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_DESKTOP_VIEWPORT"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
// we need to know the number of desktops, therefore setting it
|
||||
rootInfo.setNumberOfDesktops(4);
|
||||
NETPoint desktopOne;
|
||||
desktopOne.x = 100;
|
||||
desktopOne.y = 50;
|
||||
NETPoint desktopTwo;
|
||||
desktopTwo.x = 200;
|
||||
desktopTwo.y = 100;
|
||||
rootInfo.setDesktopViewport(1, desktopOne);
|
||||
rootInfo.setDesktopViewport(2, desktopTwo);
|
||||
|
||||
const NETPoint compareZero = rootInfo.desktopViewport(0);
|
||||
QCOMPARE(compareZero.x, 0);
|
||||
QCOMPARE(compareZero.y, 0);
|
||||
const NETPoint compareOne = rootInfo.desktopViewport(1);
|
||||
QCOMPARE(compareOne.x, desktopOne.x);
|
||||
QCOMPARE(compareOne.y, desktopOne.y);
|
||||
const NETPoint compareTwo = rootInfo.desktopViewport(2);
|
||||
QCOMPARE(compareTwo.x, desktopTwo.x);
|
||||
QCOMPARE(compareTwo.y, desktopTwo.y);
|
||||
const NETPoint compareThree = rootInfo.desktopViewport(3);
|
||||
QCOMPARE(compareThree.x, 0);
|
||||
QCOMPARE(compareThree.y, 0);
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_CARDINAL, 0, 8);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(8));
|
||||
uint32_t *data = reinterpret_cast<uint32_t *>(xcb_get_property_value(reply.get()));
|
||||
QCOMPARE(data[0], uint32_t(desktopOne.x));
|
||||
QCOMPARE(data[1], uint32_t(desktopOne.y));
|
||||
QCOMPARE(data[2], uint32_t(desktopTwo.x));
|
||||
QCOMPARE(data[3], uint32_t(desktopTwo.y));
|
||||
QCOMPARE(data[4], uint32_t(0));
|
||||
QCOMPARE(data[5], uint32_t(0));
|
||||
QCOMPARE(data[6], uint32_t(0));
|
||||
QCOMPARE(data[7], uint32_t(0));
|
||||
|
||||
// wait for our property - two events
|
||||
waitForPropertyChange(&rootInfo, atom, NET::DesktopViewport);
|
||||
waitForPropertyChange(&rootInfo, atom, NET::DesktopViewport);
|
||||
const NETPoint compareOne2 = rootInfo.desktopViewport(1);
|
||||
QCOMPARE(compareOne2.x, desktopOne.x);
|
||||
QCOMPARE(compareOne2.y, desktopOne.y);
|
||||
const NETPoint compareTwo2 = rootInfo.desktopViewport(2);
|
||||
QCOMPARE(compareTwo2.x, desktopTwo.x);
|
||||
QCOMPARE(compareTwo2.y, desktopTwo.y);
|
||||
const NETPoint compareThree2 = rootInfo.desktopViewport(3);
|
||||
QCOMPARE(compareThree2.x, 0);
|
||||
QCOMPARE(compareThree2.y, 0);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testShowingDesktop_data()
|
||||
{
|
||||
QTest::addColumn<bool>("set");
|
||||
QTest::addColumn<uint32_t>("setValue");
|
||||
|
||||
QTest::newRow("true") << true << uint32_t(1);
|
||||
QTest::newRow("false") << false << uint32_t(0);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testShowingDesktop()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_SHOWING_DESKTOP"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
QFETCH(bool, set);
|
||||
rootInfo.setShowingDesktop(set);
|
||||
QCOMPARE(rootInfo.showingDesktop(), set);
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_CARDINAL, 0, 1);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(1));
|
||||
QTEST(reinterpret_cast<uint32_t *>(xcb_get_property_value(reply.get()))[0], "setValue");
|
||||
|
||||
// wait for our property
|
||||
waitForPropertyChange(&rootInfo, atom, NET::Property(0), NET::WM2ShowingDesktop);
|
||||
QCOMPARE(rootInfo.showingDesktop(), set);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testWorkArea()
|
||||
{
|
||||
KXUtils::Atom atom(connection(), QByteArrayLiteral("_NET_WORKAREA"));
|
||||
QVERIFY(connection());
|
||||
NETRootInfo
|
||||
rootInfo(connection(), m_supportWindow, s_wmName, NET::WMAllProperties, NET::AllTypesMask, NET::States(~0u), NET::WM2AllProperties, NET::Actions(~0u));
|
||||
// we need to know the number of desktops, therefore setting it
|
||||
rootInfo.setNumberOfDesktops(4);
|
||||
NETRect desktopOne;
|
||||
desktopOne.pos.x = 10;
|
||||
desktopOne.pos.y = 5;
|
||||
desktopOne.size.width = 1000;
|
||||
desktopOne.size.height = 800;
|
||||
NETRect desktopTwo;
|
||||
desktopTwo.pos.x = 20;
|
||||
desktopTwo.pos.y = 10;
|
||||
desktopTwo.size.width = 800;
|
||||
desktopTwo.size.height = 750;
|
||||
rootInfo.setWorkArea(1, desktopOne);
|
||||
rootInfo.setWorkArea(2, desktopTwo);
|
||||
|
||||
const NETRect compareZero = rootInfo.workArea(0);
|
||||
QCOMPARE(compareZero.pos.x, 0);
|
||||
QCOMPARE(compareZero.pos.y, 0);
|
||||
QCOMPARE(compareZero.size.width, 0);
|
||||
QCOMPARE(compareZero.size.height, 0);
|
||||
const NETRect compareOne = rootInfo.workArea(1);
|
||||
QCOMPARE(compareOne.pos.x, desktopOne.pos.x);
|
||||
QCOMPARE(compareOne.pos.y, desktopOne.pos.y);
|
||||
QCOMPARE(compareOne.size.width, desktopOne.size.width);
|
||||
QCOMPARE(compareOne.size.height, desktopOne.size.height);
|
||||
const NETRect compareTwo = rootInfo.workArea(2);
|
||||
QCOMPARE(compareTwo.pos.x, desktopTwo.pos.x);
|
||||
QCOMPARE(compareTwo.pos.y, desktopTwo.pos.y);
|
||||
QCOMPARE(compareTwo.size.width, desktopTwo.size.width);
|
||||
QCOMPARE(compareTwo.size.height, desktopTwo.size.height);
|
||||
const NETRect compareThree = rootInfo.workArea(3);
|
||||
QCOMPARE(compareThree.pos.x, 0);
|
||||
QCOMPARE(compareThree.pos.y, 0);
|
||||
QCOMPARE(compareThree.size.width, 0);
|
||||
QCOMPARE(compareThree.size.height, 0);
|
||||
|
||||
// compare with the X property
|
||||
QVERIFY(atom != XCB_ATOM_NONE);
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(connection(), false, rootInfo.rootWindow(), atom, XCB_ATOM_CARDINAL, 0, 16);
|
||||
Property reply(xcb_get_property_reply(connection(), cookie, nullptr));
|
||||
QVERIFY(reply);
|
||||
QCOMPARE(reply->format, uint8_t(32));
|
||||
QCOMPARE(reply->value_len, uint32_t(16));
|
||||
uint32_t *data = reinterpret_cast<uint32_t *>(xcb_get_property_value(reply.get()));
|
||||
QCOMPARE(data[0], uint32_t(desktopOne.pos.x));
|
||||
QCOMPARE(data[1], uint32_t(desktopOne.pos.y));
|
||||
QCOMPARE(data[2], uint32_t(desktopOne.size.width));
|
||||
QCOMPARE(data[3], uint32_t(desktopOne.size.height));
|
||||
QCOMPARE(data[4], uint32_t(desktopTwo.pos.x));
|
||||
QCOMPARE(data[5], uint32_t(desktopTwo.pos.y));
|
||||
QCOMPARE(data[6], uint32_t(desktopTwo.size.width));
|
||||
QCOMPARE(data[7], uint32_t(desktopTwo.size.height));
|
||||
QCOMPARE(data[8], uint32_t(0));
|
||||
QCOMPARE(data[9], uint32_t(0));
|
||||
QCOMPARE(data[10], uint32_t(0));
|
||||
QCOMPARE(data[11], uint32_t(0));
|
||||
QCOMPARE(data[12], uint32_t(0));
|
||||
QCOMPARE(data[13], uint32_t(0));
|
||||
QCOMPARE(data[14], uint32_t(0));
|
||||
QCOMPARE(data[15], uint32_t(0));
|
||||
|
||||
// wait for our property - two events
|
||||
waitForPropertyChange(&rootInfo, atom, NET::WorkArea);
|
||||
waitForPropertyChange(&rootInfo, atom, NET::WorkArea);
|
||||
const NETRect compareOne2 = rootInfo.workArea(1);
|
||||
QCOMPARE(compareOne2.pos.x, desktopOne.pos.x);
|
||||
QCOMPARE(compareOne2.pos.y, desktopOne.pos.y);
|
||||
QCOMPARE(compareOne2.size.width, desktopOne.size.width);
|
||||
QCOMPARE(compareOne2.size.height, desktopOne.size.height);
|
||||
const NETRect compareTwo2 = rootInfo.workArea(2);
|
||||
QCOMPARE(compareTwo2.pos.x, desktopTwo.pos.x);
|
||||
QCOMPARE(compareTwo2.pos.y, desktopTwo.pos.y);
|
||||
QCOMPARE(compareTwo2.size.width, desktopTwo.size.width);
|
||||
QCOMPARE(compareTwo2.size.height, desktopTwo.size.height);
|
||||
const NETRect compareThree2 = rootInfo.workArea(3);
|
||||
QCOMPARE(compareThree2.pos.x, 0);
|
||||
QCOMPARE(compareThree2.pos.y, 0);
|
||||
QCOMPARE(compareThree2.size.width, 0);
|
||||
QCOMPARE(compareThree2.size.height, 0);
|
||||
}
|
||||
|
||||
void NetRootInfoTestWM::testDontCrashMapViewports()
|
||||
{
|
||||
QProcess p;
|
||||
const QString processName = QFINDTESTDATA("dontcrashmapviewport");
|
||||
QVERIFY(!processName.isEmpty());
|
||||
|
||||
p.start(processName, QStringList());
|
||||
QVERIFY(p.waitForFinished());
|
||||
QCOMPARE(p.exitStatus(), QProcess::NormalExit);
|
||||
QCOMPARE(p.exitCode(), 0);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(NetRootInfoTestWM)
|
||||
|
||||
#include "netrootinfotestwm.moc"
|
||||
Reference in New Issue
Block a user