Client: Add wl_output tests
Also removes overlapping old tests and adds a (currently failing) test for QTBUG-72828. Task-number: QTBUG-72828 Change-Id: Id93d5872ed1c4f181935c1e493e9d8d0ae9cfaf3 Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@liri.io>
This commit is contained in:
parent
c34abdb08b
commit
badf0575a2
@ -4,6 +4,7 @@ SUBDIRS += \
|
||||
client \
|
||||
fullscreenshellv1 \
|
||||
iviapplication \
|
||||
output \
|
||||
seatv4 \
|
||||
surface \
|
||||
wl_connect \
|
||||
|
@ -167,11 +167,6 @@ public slots:
|
||||
}
|
||||
|
||||
private slots:
|
||||
void primaryScreen();
|
||||
void screens();
|
||||
void addScreenWithGeometryChange();
|
||||
void windowScreens();
|
||||
void removePrimaryScreen();
|
||||
void createDestroyWindow();
|
||||
void activeWindowFollowsKeyboardFocus();
|
||||
void events();
|
||||
@ -188,117 +183,6 @@ private:
|
||||
MockCompositor *compositor = nullptr;
|
||||
};
|
||||
|
||||
void tst_WaylandClient::primaryScreen()
|
||||
{
|
||||
compositor->setOutputMode(screenSize);
|
||||
QTRY_COMPARE(QGuiApplication::primaryScreen()->size(), screenSize);
|
||||
}
|
||||
|
||||
void tst_WaylandClient::screens()
|
||||
{
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
compositor->sendAddOutput();
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
QSharedPointer<MockOutput> secondOutput;
|
||||
QTRY_VERIFY(secondOutput = compositor->output(1));
|
||||
compositor->sendRemoveOutput(secondOutput);
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
}
|
||||
|
||||
//QTBUG-62044
|
||||
void tst_WaylandClient::addScreenWithGeometryChange()
|
||||
{
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
const QRect oldGeometry = QGuiApplication::primaryScreen()->geometry();
|
||||
compositor->sendAddOutput();
|
||||
|
||||
// Move the primary screen to the right
|
||||
const QRect newGeometry(QPoint(screenSize.width(), 0), screenSize);
|
||||
Q_ASSERT(oldGeometry != newGeometry);
|
||||
compositor->sendOutputGeometry(compositor->output(0), newGeometry);
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
QTRY_COMPARE(QGuiApplication::primaryScreen()->geometry(), newGeometry);
|
||||
|
||||
compositor->sendRemoveOutput(compositor->output(1));
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
|
||||
// Move the screen back
|
||||
compositor->sendOutputGeometry(compositor->output(0), oldGeometry);
|
||||
QTRY_COMPARE(QGuiApplication::primaryScreen()->geometry(), oldGeometry);
|
||||
}
|
||||
|
||||
void tst_WaylandClient::windowScreens()
|
||||
{
|
||||
QSharedPointer<MockOutput> firstOutput;
|
||||
QTRY_VERIFY(firstOutput = compositor->output());
|
||||
|
||||
TestWindow window;
|
||||
window.show();
|
||||
|
||||
QSharedPointer<MockSurface> surface;
|
||||
QTRY_VERIFY(surface = compositor->surface());
|
||||
compositor->sendShellSurfaceConfigure(surface);
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
QScreen *primaryScreen = QGuiApplication::screens().first();
|
||||
QCOMPARE(window.screen(), primaryScreen);
|
||||
|
||||
compositor->sendAddOutput();
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
QScreen *secondaryScreen = QGuiApplication::screens().at(1);
|
||||
QVERIFY(secondaryScreen);
|
||||
|
||||
window.setScreen(secondaryScreen);
|
||||
QCOMPARE(window.screen(), secondaryScreen);
|
||||
|
||||
QSharedPointer<MockOutput> secondOutput;
|
||||
QTRY_VERIFY(secondOutput = compositor->output(1));
|
||||
compositor->sendSurfaceEnter(surface, firstOutput);
|
||||
|
||||
compositor->sendSurfaceEnter(surface, secondOutput);
|
||||
QTRY_COMPARE(window.screen(), primaryScreen);
|
||||
|
||||
compositor->sendSurfaceLeave(surface, firstOutput);
|
||||
QTRY_COMPARE(window.screen(), secondaryScreen);
|
||||
|
||||
compositor->sendRemoveOutput(secondOutput);
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
QCOMPARE(window.screen(), primaryScreen);
|
||||
}
|
||||
|
||||
void tst_WaylandClient::removePrimaryScreen()
|
||||
{
|
||||
QSharedPointer<MockOutput> firstOutput;
|
||||
QTRY_VERIFY(firstOutput = compositor->output());
|
||||
|
||||
TestWindow window;
|
||||
window.show();
|
||||
|
||||
QSharedPointer<MockSurface> surface;
|
||||
QTRY_VERIFY(surface = compositor->surface());
|
||||
compositor->sendShellSurfaceConfigure(surface);
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
QScreen *primaryScreen = QGuiApplication::screens().first();
|
||||
QCOMPARE(window.screen(), primaryScreen);
|
||||
|
||||
compositor->sendAddOutput();
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
QTRY_COMPARE(QGuiApplication::primaryScreen()->virtualSiblings().size(), 2);
|
||||
QScreen *secondaryScreen = QGuiApplication::screens().at(1);
|
||||
QVERIFY(secondaryScreen);
|
||||
|
||||
compositor->sendRemoveOutput(firstOutput);
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
|
||||
compositor->sendMousePress(surface, window.frameOffset() + QPoint(10, 10));
|
||||
QTRY_COMPARE(window.mousePressEventCount, 1);
|
||||
compositor->sendMouseRelease(surface);
|
||||
QTRY_COMPARE(window.mouseReleaseEventCount, 1);
|
||||
}
|
||||
|
||||
void tst_WaylandClient::createDestroyWindow()
|
||||
{
|
||||
TestWindow window;
|
||||
|
5
tests/auto/wayland/output/output.pro
Normal file
5
tests/auto/wayland/output/output.pro
Normal file
@ -0,0 +1,5 @@
|
||||
include (../shared/shared.pri)
|
||||
|
||||
TARGET = tst_output
|
||||
SOURCES += tst_output.cpp
|
||||
|
231
tests/auto/wayland/output/tst_output.cpp
Normal file
231
tests/auto/wayland/output/tst_output.cpp
Normal file
@ -0,0 +1,231 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "mockcompositor.h"
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QRasterWindow>
|
||||
|
||||
using namespace MockCompositor;
|
||||
|
||||
class tst_output : public QObject, private DefaultCompositor
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
m_config.autoConfigure = true;
|
||||
m_config.autoEnter = false;
|
||||
}
|
||||
void cleanup()
|
||||
{
|
||||
QCOMPOSITOR_COMPARE(getAll<Output>().size(), 1); // Only the default output should be left
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage()));
|
||||
}
|
||||
void primaryScreen();
|
||||
void secondaryHiDpiScreen();
|
||||
void addScreenWithGeometryChange();
|
||||
void windowScreens();
|
||||
void removePrimaryScreen();
|
||||
void screenOrder();
|
||||
};
|
||||
|
||||
void tst_output::primaryScreen()
|
||||
{
|
||||
// Verify that the client has bound to the output global
|
||||
QCOMPOSITOR_TRY_COMPARE(output()->resourceMap().size(), 1);
|
||||
QTRY_VERIFY(QGuiApplication::primaryScreen());
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
QCOMPARE(screen->manufacturer(), "Make");
|
||||
QCOMPARE(screen->model(), "Model");
|
||||
QCOMPARE(screen->size(), QSize(1920, 1080));
|
||||
QCOMPARE(screen->refreshRate(), 60);
|
||||
QCOMPARE(qRound(screen->physicalDotsPerInch()), 96 / screen->devicePixelRatio());
|
||||
QCOMPARE(screen->devicePixelRatio(), 1);
|
||||
QCOMPARE(screen->logicalDotsPerInch(), 96);
|
||||
}
|
||||
|
||||
void tst_output::secondaryHiDpiScreen()
|
||||
{
|
||||
exec([=] {
|
||||
OutputData d;
|
||||
d.position = {1920, 0}; // in global compositor space (not pixels)
|
||||
d.mode.resolution = {800, 640};
|
||||
d.physicalSize = d.mode.physicalSizeForDpi(200);
|
||||
d.scale = 2;
|
||||
add<Output>(d);
|
||||
});
|
||||
|
||||
// Verify that the client has bound to the output global
|
||||
QCOMPOSITOR_TRY_VERIFY(output(1) && output(1)->resourceMap().size() == 1);
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
QScreen *screen = QGuiApplication::screens()[1];
|
||||
QCOMPARE(screen->refreshRate(), 60);
|
||||
QCOMPARE(screen->devicePixelRatio(), 2);
|
||||
QCOMPARE(screen->logicalDotsPerInch(), 96);
|
||||
|
||||
// Dots currently means device pixels, not actual pixels (see QTBUG-62649)
|
||||
QCOMPARE(qRound(screen->physicalDotsPerInch() * screen->devicePixelRatio()), 200);
|
||||
|
||||
// Size is in logical pixel coordinates
|
||||
QCOMPARE(screen->size(), QSize(800, 640) / 2);
|
||||
QCOMPARE(screen->geometry(), QRect(QPoint(1920, 0), QSize(400, 320)));
|
||||
QCOMPARE(screen->virtualGeometry(), QRect(QPoint(0, 0), QSize(1920 + 800 / 2, 1080)));
|
||||
|
||||
exec([=] { remove(output(1)); });
|
||||
}
|
||||
|
||||
// QTBUG-62044
|
||||
void tst_output::addScreenWithGeometryChange()
|
||||
{
|
||||
const QPoint initialPosition = exec([=] { return output(0)->m_data.position; });
|
||||
|
||||
exec([=] {
|
||||
auto *oldOutput = output(0);
|
||||
auto *newOutput = add<Output>();
|
||||
newOutput->m_data.mode.resolution = {1280, 720};
|
||||
// Move the primary output to the right
|
||||
QPoint newPosition(newOutput->m_data.mode.resolution.width(), 0);
|
||||
Q_ASSERT(newPosition != initialPosition);
|
||||
oldOutput->m_data.position = newPosition;
|
||||
oldOutput->sendGeometry();
|
||||
oldOutput->sendDone();
|
||||
});
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
QTRY_COMPARE(QGuiApplication::primaryScreen()->geometry(), QRect(QPoint(1280, 0), QSize(1920, 1080)));
|
||||
|
||||
// Remove the extra output and move the old one back
|
||||
exec([=] {
|
||||
remove(output(1));
|
||||
output()->m_data.position = initialPosition;
|
||||
output()->sendGeometry();
|
||||
output()->sendDone();
|
||||
});
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
QTRY_COMPARE(QGuiApplication::primaryScreen()->geometry(), QRect(QPoint(0, 0), QSize(1920, 1080)));
|
||||
}
|
||||
|
||||
void tst_output::windowScreens()
|
||||
{
|
||||
QRasterWindow window;
|
||||
window.resize(400, 320);
|
||||
window.show();
|
||||
QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
QScreen *primaryScreen = QGuiApplication::screens().first();
|
||||
QCOMPARE(window.screen(), primaryScreen);
|
||||
|
||||
exec([=] { add<Output>(); });
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
QScreen *secondaryScreen = QGuiApplication::screens().at(1);
|
||||
QVERIFY(secondaryScreen);
|
||||
|
||||
window.setScreen(secondaryScreen);
|
||||
QCOMPARE(window.screen(), secondaryScreen);
|
||||
|
||||
exec([=] {
|
||||
xdgToplevel()->surface()->sendEnter(output(0));
|
||||
xdgToplevel()->surface()->sendEnter(output(1));
|
||||
});
|
||||
|
||||
QTRY_COMPARE(window.screen(), primaryScreen);
|
||||
|
||||
exec([=] {
|
||||
xdgToplevel()->surface()->sendLeave(output(0));
|
||||
});
|
||||
QTRY_COMPARE(window.screen(), secondaryScreen);
|
||||
|
||||
exec([=] {
|
||||
remove(output(1));
|
||||
});
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
QCOMPARE(window.screen(), primaryScreen);
|
||||
}
|
||||
|
||||
void tst_output::removePrimaryScreen()
|
||||
{
|
||||
QRasterWindow window;
|
||||
window.resize(400, 320);
|
||||
window.show();
|
||||
QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
QScreen *primaryScreen = QGuiApplication::screens().first();
|
||||
QCOMPARE(window.screen(), primaryScreen);
|
||||
|
||||
// Add a clone of the primary output
|
||||
exec([&] { add<Output>(output()->m_data); });
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
QTRY_COMPARE(QGuiApplication::primaryScreen()->virtualSiblings().size(), 2);
|
||||
QScreen *secondaryScreen = QGuiApplication::screens().at(1);
|
||||
QVERIFY(secondaryScreen);
|
||||
|
||||
exec([&] { remove(output()); });
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
|
||||
exec([&] {
|
||||
auto *surface = xdgToplevel()->surface();
|
||||
pointer()->sendEnter(surface, {32, 32});
|
||||
pointer()->sendButton(client(), BTN_LEFT, 1);
|
||||
pointer()->sendButton(client(), BTN_LEFT, 0);
|
||||
});
|
||||
|
||||
// Wait to make sure mouse events dont't cause a crash now that the screen has changed
|
||||
xdgPingAndWaitForPong();
|
||||
}
|
||||
|
||||
// QTBUG-72828
|
||||
void tst_output::screenOrder()
|
||||
{
|
||||
exec([=] {
|
||||
add<Output>()->m_data.model = "Screen 1";
|
||||
add<Output>()->m_data.model = "Screen 2";
|
||||
});
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::screens().size(), 3);
|
||||
const auto screens = QGuiApplication::screens();
|
||||
|
||||
QEXPECT_FAIL(nullptr, "TODO: fix screen order", Continue);
|
||||
QCOMPARE(screens[1]->model(), "Screen 1");
|
||||
|
||||
QEXPECT_FAIL(nullptr, "TODO: fix screen order", Continue);
|
||||
QCOMPARE(screens[2]->model(), "Screen 2");
|
||||
|
||||
exec([=] {
|
||||
remove(output(2));
|
||||
remove(output(1));
|
||||
});
|
||||
}
|
||||
|
||||
QCOMPOSITOR_TEST_MAIN(tst_output)
|
||||
#include "tst_output.moc"
|
@ -256,8 +256,10 @@ void tst_seatv4::scaledCursor()
|
||||
QSKIP("Currently broken and should be fixed");
|
||||
// Add a highdpi output
|
||||
exec([&] {
|
||||
int scale = 2;
|
||||
add<Output>(scale);
|
||||
OutputData d;
|
||||
d.scale = 2;
|
||||
d.position = {1920, 0};
|
||||
add<Output>(d);
|
||||
});
|
||||
|
||||
QRasterWindow window;
|
||||
@ -282,7 +284,7 @@ void tst_seatv4::scaledCursor()
|
||||
QCOMPOSITOR_TRY_COMPARE(pointer()->cursorSurface()->m_committed.buffer->size(), unscaledPixelSize * 2);
|
||||
|
||||
// Remove the extra output to clean up for the next test
|
||||
exec([&] { remove(getAll<Output>()[1]); });
|
||||
exec([&] { remove(output(1)); });
|
||||
}
|
||||
|
||||
QCOMPOSITOR_TEST_MAIN(tst_seatv4)
|
||||
|
@ -97,8 +97,8 @@ void CoreCompositor::add(Global *global)
|
||||
void CoreCompositor::remove(Global *global)
|
||||
{
|
||||
warnIfNotLockedByThread(Q_FUNC_INFO);
|
||||
//TODO: Need to delete global as well!
|
||||
m_globals.removeAll(global);
|
||||
delete global;
|
||||
}
|
||||
|
||||
uint CoreCompositor::nextSerial()
|
||||
|
@ -125,28 +125,55 @@ QString WlCompositor::dirtyMessage()
|
||||
return "Dirty, surfaces left:\n\t" + messages.join("\n\t");
|
||||
}
|
||||
|
||||
void Output::sendGeometry()
|
||||
{
|
||||
const auto resources = resourceMap().values();
|
||||
for (auto r : resources)
|
||||
sendGeometry(r);
|
||||
}
|
||||
|
||||
void Output::sendGeometry(Resource *resource)
|
||||
{
|
||||
// TODO: check resource version as well?
|
||||
wl_output::send_geometry(resource->handle,
|
||||
m_data.position.x(), m_data.position.y(),
|
||||
m_data.physicalSize.width(), m_data.physicalSize.height(),
|
||||
m_data.subpixel, m_data.make, m_data.model, m_data.transform);
|
||||
}
|
||||
|
||||
void Output::sendScale(int factor)
|
||||
{
|
||||
Q_ASSERT(m_version >= WL_OUTPUT_SCALE_SINCE_VERSION);
|
||||
m_scale = factor;
|
||||
m_data.scale = factor;
|
||||
const auto resources = resourceMap().values();
|
||||
for (auto r: resources)
|
||||
wl_output::send_scale(r->handle, factor);
|
||||
for (auto r : resources)
|
||||
sendScale(r);
|
||||
}
|
||||
|
||||
void Output::sendScale(Resource *resource)
|
||||
{
|
||||
Q_ASSERT(m_version >= WL_OUTPUT_SCALE_SINCE_VERSION);
|
||||
// TODO: check resource version as well?
|
||||
wl_output::send_scale(resource->handle, m_data.scale);
|
||||
}
|
||||
|
||||
void Output::sendDone()
|
||||
{
|
||||
Q_ASSERT(m_version >= WL_OUTPUT_DONE_SINCE_VERSION);
|
||||
// TODO: check resource version as well?
|
||||
const auto resources = resourceMap().values();
|
||||
for (auto r: resources)
|
||||
for (auto r : resources)
|
||||
wl_output::send_done(r->handle);
|
||||
}
|
||||
|
||||
void Output::output_bind_resource(QtWaylandServer::wl_output::Resource *resource)
|
||||
{
|
||||
sendGeometry(resource);
|
||||
send_mode(resource->handle, mode_preferred | mode_current,
|
||||
m_data.mode.resolution.width(), m_data.mode.resolution.height(), m_data.mode.refreshRate);
|
||||
if (m_version >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
||||
wl_output::send_scale(resource->handle, m_scale);
|
||||
//TODO: send other required stuff as well
|
||||
sendScale(resource);
|
||||
|
||||
if (m_version >= WL_OUTPUT_DONE_SINCE_VERSION)
|
||||
wl_output::send_done(resource->handle);
|
||||
}
|
||||
|
@ -171,20 +171,59 @@ public:
|
||||
// TODO
|
||||
};
|
||||
|
||||
struct OutputMode {
|
||||
explicit OutputMode() = default;
|
||||
explicit OutputMode(const QSize &resolution, int refreshRate = 60000)
|
||||
: resolution(resolution), refreshRate(refreshRate)
|
||||
{}
|
||||
QSize resolution = QSize(1920, 1080);
|
||||
int refreshRate = 60000; // In mHz
|
||||
//TODO: flags (they're currently hard-coded)
|
||||
|
||||
// in mm
|
||||
QSize physicalSizeForDpi(int dpi) { return (QSizeF(resolution) * 25.4 / dpi).toSize(); }
|
||||
};
|
||||
|
||||
struct OutputData {
|
||||
using Subpixel = QtWaylandServer::wl_output::subpixel;
|
||||
using Transform = QtWaylandServer::wl_output::transform;
|
||||
explicit OutputData() = default;
|
||||
|
||||
// for geometry event
|
||||
QPoint position;
|
||||
QSize physicalSize = QSize(0, 0); // means unknown physical size
|
||||
QString make = "Make";
|
||||
QString model = "Model";
|
||||
Subpixel subpixel = Subpixel::subpixel_unknown;
|
||||
Transform transform = Transform::transform_normal;
|
||||
|
||||
int scale = 1; // for scale event
|
||||
OutputMode mode; // for mode event
|
||||
};
|
||||
|
||||
class Output : public Global, public QtWaylandServer::wl_output
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Output(CoreCompositor *compositor, int scale = 1, int version = 2)
|
||||
explicit Output(CoreCompositor *compositor, OutputData data = OutputData(), int version = 2)
|
||||
: QtWaylandServer::wl_output(compositor->m_display, version)
|
||||
, m_scale(scale)
|
||||
, m_data(std::move(data))
|
||||
, m_version(version)
|
||||
{}
|
||||
void sendScale(int factor);
|
||||
|
||||
void send_geometry() = delete;
|
||||
void sendGeometry();
|
||||
void sendGeometry(Resource *resource); // Sends to only one client
|
||||
|
||||
void send_scale(int32_t factor) = delete;
|
||||
void send_scale(struct ::wl_resource *resource, int32_t factor) = delete;
|
||||
void sendScale(int factor);
|
||||
void sendScale(Resource *resource); // Sends current scale to only one client
|
||||
|
||||
void sendDone();
|
||||
int m_scale = 1;
|
||||
|
||||
int scale() const { return m_data.scale; }
|
||||
|
||||
OutputData m_data;
|
||||
int m_version = 1; // TODO: remove on libwayland upgrade
|
||||
|
||||
protected:
|
||||
|
@ -39,7 +39,8 @@ DefaultCompositor::DefaultCompositor()
|
||||
// Legacy versions can override in separate tests by removing and adding.
|
||||
add<WlCompositor>();
|
||||
add<SubCompositor>();
|
||||
add<Output>();
|
||||
auto *output = add<Output>();
|
||||
output->m_data.physicalSize = output->m_data.mode.physicalSizeForDpi(96);
|
||||
add<Seat>(Seat::capability_pointer);
|
||||
add<XdgWmBase>();
|
||||
add<Shm>();
|
||||
|
@ -47,6 +47,7 @@ class DefaultCompositor : public CoreCompositor
|
||||
public:
|
||||
explicit DefaultCompositor();
|
||||
// Convenience functions
|
||||
Output *output(int i = 0) { return getAll<Output>().value(i, nullptr); }
|
||||
Surface *surface(int i = 0) { return get<WlCompositor>()->m_surfaces.value(i, nullptr); }
|
||||
XdgSurface *xdgSurface(int i = 0) { return get<XdgWmBase>()->m_xdgSurfaces.value(i, nullptr); }
|
||||
XdgToplevel *xdgToplevel(int i = 0) { return get<XdgWmBase>()->toplevel(i); }
|
||||
|
@ -183,43 +183,6 @@ void MockCompositor::sendDataDeviceLeave(const QSharedPointer<MockSurface> &surf
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void MockCompositor::sendAddOutput()
|
||||
{
|
||||
Command command = makeCommand(Impl::Compositor::sendAddOutput, m_compositor);
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void MockCompositor::sendRemoveOutput(const QSharedPointer<MockOutput> &output)
|
||||
{
|
||||
Command command = makeCommand(Impl::Compositor::sendRemoveOutput, m_compositor);
|
||||
command.parameters << QVariant::fromValue(output);
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void MockCompositor::sendOutputGeometry(const QSharedPointer<MockOutput> &output, const QRect &geometry)
|
||||
{
|
||||
Command command = makeCommand(Impl::Compositor::sendOutputGeometry, m_compositor);
|
||||
command.parameters << QVariant::fromValue(output);
|
||||
command.parameters << QVariant::fromValue(geometry);
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void MockCompositor::sendSurfaceEnter(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output)
|
||||
{
|
||||
Command command = makeCommand(Impl::Compositor::sendSurfaceEnter, m_compositor);
|
||||
command.parameters << QVariant::fromValue(surface);
|
||||
command.parameters << QVariant::fromValue(output);
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void MockCompositor::sendSurfaceLeave(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output)
|
||||
{
|
||||
Command command = makeCommand(Impl::Compositor::sendSurfaceLeave, m_compositor);
|
||||
command.parameters << QVariant::fromValue(surface);
|
||||
command.parameters << QVariant::fromValue(output);
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void MockCompositor::sendShellSurfaceConfigure(const QSharedPointer<MockSurface> surface, const QSize &size)
|
||||
{
|
||||
Command command = makeCommand(Impl::Compositor::sendShellSurfaceConfigure, m_compositor);
|
||||
|
@ -98,11 +98,6 @@ public:
|
||||
static void sendDataDeviceLeave(void *data, const QList<QVariant> ¶meters);
|
||||
static void waitForStartDrag(void *data, const QList<QVariant> ¶meters);
|
||||
static void setOutputMode(void *compositor, const QList<QVariant> ¶meters);
|
||||
static void sendAddOutput(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendRemoveOutput(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendOutputGeometry(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendSurfaceEnter(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendSurfaceLeave(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendShellSurfaceConfigure(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendIviSurfaceConfigure(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendXdgToplevelV6Configure(void *data, const QList<QVariant> ¶meters);
|
||||
@ -239,9 +234,6 @@ public:
|
||||
void sendDataDeviceMotion(const QPoint &position);
|
||||
void sendDataDeviceDrop(const QSharedPointer<MockSurface> &surface);
|
||||
void sendDataDeviceLeave(const QSharedPointer<MockSurface> &surface);
|
||||
void sendAddOutput();
|
||||
void sendRemoveOutput(const QSharedPointer<MockOutput> &output);
|
||||
void sendOutputGeometry(const QSharedPointer<MockOutput> &output, const QRect &geometry);
|
||||
void sendSurfaceEnter(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
|
||||
void sendSurfaceLeave(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
|
||||
void sendShellSurfaceConfigure(const QSharedPointer<MockSurface> surface, const QSize &size = QSize(0, 0));
|
||||
|
@ -33,37 +33,6 @@
|
||||
|
||||
namespace Impl {
|
||||
|
||||
void Compositor::sendAddOutput(void *data, const QList<QVariant> ¶meters) {
|
||||
Q_UNUSED(parameters);
|
||||
Compositor *compositor = static_cast<Compositor *>(data);
|
||||
auto output = new Output(compositor->m_display, QSize(1920, 1200), QPoint(0, 0));
|
||||
compositor->m_outputs.append(output);
|
||||
|
||||
// Wait for the client to bind to the output
|
||||
while (output->resourceMap().isEmpty())
|
||||
compositor->dispatchEvents();
|
||||
}
|
||||
|
||||
void Compositor::sendRemoveOutput(void *data, const QList<QVariant> ¶meters) {
|
||||
Compositor *compositor = static_cast<Compositor *>(data);
|
||||
Q_ASSERT(compositor);
|
||||
Output *output = resolveOutput(parameters.first());
|
||||
Q_ASSERT(output);
|
||||
bool wasRemoved = compositor->m_outputs.removeOne(output);
|
||||
Q_ASSERT(wasRemoved);
|
||||
delete output;
|
||||
}
|
||||
|
||||
void Compositor::sendOutputGeometry(void *data, const QList<QVariant> ¶meters)
|
||||
{
|
||||
Compositor *compositor = static_cast<Compositor *>(data);
|
||||
Q_ASSERT(compositor);
|
||||
Output *output = resolveOutput(parameters.first());
|
||||
Q_ASSERT(output);
|
||||
QRect geometry = parameters.at(1).toRect();
|
||||
output->sendGeometryAndMode(geometry);
|
||||
}
|
||||
|
||||
void Compositor::setOutputMode(void *data, const QList<QVariant> ¶meters)
|
||||
{
|
||||
Compositor *compositor = static_cast<Compositor *>(data);
|
||||
@ -91,17 +60,6 @@ void Output::setCurrentMode(const QSize &size)
|
||||
}
|
||||
}
|
||||
|
||||
void Output::sendGeometryAndMode(const QRect &geometry)
|
||||
{
|
||||
m_size = geometry.size();
|
||||
m_position = geometry.topLeft();
|
||||
for (Resource *resource : resourceMap()) {
|
||||
sendGeometry(resource);
|
||||
sendCurrentMode(resource);
|
||||
send_done(resource->handle);
|
||||
}
|
||||
}
|
||||
|
||||
void Output::output_bind_resource(QtWaylandServer::wl_output::Resource *resource)
|
||||
{
|
||||
sendGeometry(resource);
|
||||
|
@ -44,7 +44,6 @@ public:
|
||||
|
||||
QSharedPointer<MockOutput> mockOutput() const { return m_mockOutput; }
|
||||
void setCurrentMode(const QSize &size);
|
||||
void sendGeometryAndMode(const QRect &geometry);
|
||||
|
||||
protected:
|
||||
void output_bind_resource(Resource *resource) override;
|
||||
|
@ -35,34 +35,6 @@
|
||||
|
||||
namespace Impl {
|
||||
|
||||
void Compositor::sendSurfaceEnter(void *data, const QList<QVariant> ¶meters)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Surface *surface = resolveSurface(parameters.at(0));
|
||||
Output *output = resolveOutput(parameters.at(1));
|
||||
Q_ASSERT(surface && surface->resource());
|
||||
Q_ASSERT(output);
|
||||
auto outputResources = output->resourceMap().values(surface->resource()->client());
|
||||
Q_ASSERT(!outputResources.isEmpty());
|
||||
|
||||
for (auto outputResource : outputResources)
|
||||
surface->send_enter(outputResource->handle);
|
||||
}
|
||||
|
||||
void Compositor::sendSurfaceLeave(void *data, const QList<QVariant> ¶meters)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Surface *surface = resolveSurface(parameters.at(0));
|
||||
Output *output = resolveOutput(parameters.at(1));
|
||||
Q_ASSERT(surface && surface->resource());
|
||||
Q_ASSERT(output);
|
||||
auto outputResources = output->resourceMap().values(surface->resource()->client());
|
||||
Q_ASSERT(!outputResources.isEmpty());
|
||||
|
||||
for (auto outputResource : outputResources)
|
||||
surface->send_leave(outputResource->handle);
|
||||
}
|
||||
|
||||
void Compositor::sendShellSurfaceConfigure(void *data, const QList<QVariant> ¶meters)
|
||||
{
|
||||
Compositor *compositor = static_cast<Compositor *>(data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user