xdg-shell: Rewrite wrappers for the xdg-shell protocol
The current xdg-shell wrappers don't match existing abstractions in the xdg-shell protocol well, which makes it more difficult to refactor code that is responsible for managing configure events and geometry in kwin. Given that the xdg_decoration and the xdg_shell protocols are tightly coupled together, I had to rewrite our wrappers for the xdg_decoration protocol as well.
This commit is contained in:
parent
5955d0486d
commit
e3ad23ccd8
23 changed files with 1961 additions and 2845 deletions
|
@ -58,12 +58,11 @@ set(SERVER_LIB_SRCS
|
||||||
textinput_interface_v0.cpp
|
textinput_interface_v0.cpp
|
||||||
textinput_interface_v2.cpp
|
textinput_interface_v2.cpp
|
||||||
touch_interface.cpp
|
touch_interface.cpp
|
||||||
xdgdecoration_interface.cpp
|
xdgdecoration_v1_interface.cpp
|
||||||
xdgforeign_interface.cpp
|
xdgforeign_interface.cpp
|
||||||
xdgforeign_v2_interface.cpp
|
xdgforeign_v2_interface.cpp
|
||||||
xdgoutput_interface.cpp
|
xdgoutput_interface.cpp
|
||||||
xdgshell_interface.cpp
|
xdgshell_interface.cpp
|
||||||
xdgshell_stable_interface.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_qt_declare_logging_category(SERVER_LIB_SRCS
|
ecm_qt_declare_logging_category(SERVER_LIB_SRCS
|
||||||
|
@ -199,14 +198,14 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
||||||
BASENAME xdg-output
|
BASENAME xdg-output
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
ecm_add_qtwayland_server_protocol(SERVER_LIB_SRCS
|
||||||
PROTOCOL ${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml
|
PROTOCOL ${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml
|
||||||
BASENAME xdg-shell
|
BASENAME xdg-shell
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
ecm_add_qtwayland_server_protocol(SERVER_LIB_SRCS
|
||||||
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
|
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
|
||||||
BASENAME xdg-decoration
|
BASENAME xdg-decoration-unstable-v1
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
||||||
|
@ -387,7 +386,7 @@ set(SERVER_LIB_HEADERS
|
||||||
tablet_interface.h
|
tablet_interface.h
|
||||||
textinput_interface.h
|
textinput_interface.h
|
||||||
touch_interface.h
|
touch_interface.h
|
||||||
xdgdecoration_interface.h
|
xdgdecoration_v1_interface.h
|
||||||
xdgforeign_interface.h
|
xdgforeign_interface.h
|
||||||
xdgoutput_interface.h
|
xdgoutput_interface.h
|
||||||
xdgshell_interface.h
|
xdgshell_interface.h
|
||||||
|
|
|
@ -343,16 +343,13 @@ add_test(NAME kwayland-testXdgForeign COMMAND testXdgForeign)
|
||||||
ecm_mark_as_test(testXdgForeign)
|
ecm_mark_as_test(testXdgForeign)
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
# Test XdgShellStable
|
# Test XdgShell
|
||||||
########################################################
|
########################################################
|
||||||
set( testXdgShellStable_SRCS
|
set(testXdgShell_SRCS test_xdg_shell.cpp)
|
||||||
test_xdg_shell.cpp
|
add_executable(testXdgShell ${testXdgShell_SRCS})
|
||||||
test_xdg_shell_stable.cpp
|
target_link_libraries( testXdgShell Qt5::Test Qt5::Gui Plasma::KWaylandServer KF5::WaylandClient Wayland::Client)
|
||||||
)
|
add_test(NAME kwayland-testXdgShell COMMAND testXdgShell)
|
||||||
add_executable(testXdgShellStable ${testXdgShellStable_SRCS})
|
ecm_mark_as_test(testXdgShell)
|
||||||
target_link_libraries( testXdgShellStable Qt5::Test Qt5::Gui Plasma::KWaylandServer KF5::WaylandClient Wayland::Client)
|
|
||||||
add_test(NAME kwayland-testXdgShellStable COMMAND testXdgShellStable)
|
|
||||||
ecm_mark_as_test(testXdgShellStable)
|
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
# Test Pointer Constraints
|
# Test Pointer Constraints
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "../../src/server/display.h"
|
#include "../../src/server/display.h"
|
||||||
#include "../../src/server/compositor_interface.h"
|
#include "../../src/server/compositor_interface.h"
|
||||||
#include "../../src/server/xdgshell_interface.h"
|
#include "../../src/server/xdgshell_interface.h"
|
||||||
#include "../../src/server/xdgdecoration_interface.h"
|
#include "../../src/server/xdgdecoration_v1_interface.h"
|
||||||
|
|
||||||
class TestXdgDecoration : public QObject
|
class TestXdgDecoration : public QObject
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ private:
|
||||||
KWaylandServer::Display *m_display = nullptr;
|
KWaylandServer::Display *m_display = nullptr;
|
||||||
KWaylandServer::CompositorInterface *m_compositorInterface = nullptr;
|
KWaylandServer::CompositorInterface *m_compositorInterface = nullptr;
|
||||||
KWaylandServer::XdgShellInterface *m_xdgShellInterface = nullptr;
|
KWaylandServer::XdgShellInterface *m_xdgShellInterface = nullptr;
|
||||||
KWaylandServer::XdgDecorationManagerInterface *m_xdgDecorationManagerInterface = nullptr;
|
KWaylandServer::XdgDecorationManagerV1Interface *m_xdgDecorationManagerInterface = nullptr;
|
||||||
|
|
||||||
KWayland::Client::ConnectionThread *m_connection = nullptr;
|
KWayland::Client::ConnectionThread *m_connection = nullptr;
|
||||||
KWayland::Client::Compositor *m_compositor = nullptr;
|
KWayland::Client::Compositor *m_compositor = nullptr;
|
||||||
|
@ -59,7 +59,7 @@ void TestXdgDecoration::init()
|
||||||
using namespace KWayland::Client;
|
using namespace KWayland::Client;
|
||||||
|
|
||||||
qRegisterMetaType<XdgDecoration::Mode>();
|
qRegisterMetaType<XdgDecoration::Mode>();
|
||||||
qRegisterMetaType<XdgDecorationInterface::Mode>();
|
qRegisterMetaType<XdgToplevelDecorationV1Interface::Mode>();
|
||||||
|
|
||||||
delete m_display;
|
delete m_display;
|
||||||
m_display = new Display(this);
|
m_display = new Display(this);
|
||||||
|
@ -104,16 +104,12 @@ void TestXdgDecoration::init()
|
||||||
QVERIFY(compositorSpy.wait());
|
QVERIFY(compositorSpy.wait());
|
||||||
m_compositor = m_registry->createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this);
|
m_compositor = m_registry->createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this);
|
||||||
|
|
||||||
m_xdgShellInterface = m_display->createXdgShell(XdgShellInterfaceVersion::Stable, m_display);
|
m_xdgShellInterface = m_display->createXdgShell(m_display);
|
||||||
m_xdgShellInterface->create();
|
|
||||||
QVERIFY(m_xdgShellInterface->isValid());
|
|
||||||
QVERIFY(xdgShellSpy.wait());
|
QVERIFY(xdgShellSpy.wait());
|
||||||
m_xdgShell = m_registry->createXdgShell(xdgShellSpy.first().first().value<quint32>(),
|
m_xdgShell = m_registry->createXdgShell(xdgShellSpy.first().first().value<quint32>(),
|
||||||
xdgShellSpy.first().last().value<quint32>(), this);
|
xdgShellSpy.first().last().value<quint32>(), this);
|
||||||
|
|
||||||
m_xdgDecorationManagerInterface = m_display->createXdgDecorationManager(m_xdgShellInterface, m_display);
|
m_xdgDecorationManagerInterface = m_display->createXdgDecorationManagerV1(m_display);
|
||||||
m_xdgDecorationManagerInterface->create();
|
|
||||||
QVERIFY(m_xdgDecorationManagerInterface->isValid());
|
|
||||||
|
|
||||||
QVERIFY(xdgDecorationManagerSpy.wait());
|
QVERIFY(xdgDecorationManagerSpy.wait());
|
||||||
m_xdgDecorationManager = m_registry->createXdgDecorationManager(xdgDecorationManagerSpy.first().first().value<quint32>(),
|
m_xdgDecorationManager = m_registry->createXdgDecorationManager(xdgDecorationManagerSpy.first().first().value<quint32>(),
|
||||||
|
@ -160,13 +156,13 @@ void TestXdgDecoration::testDecoration_data()
|
||||||
{
|
{
|
||||||
using namespace KWayland::Client;
|
using namespace KWayland::Client;
|
||||||
using namespace KWaylandServer;
|
using namespace KWaylandServer;
|
||||||
QTest::addColumn<KWaylandServer::XdgDecorationInterface::Mode>("configuredMode");
|
QTest::addColumn<KWaylandServer::XdgToplevelDecorationV1Interface::Mode>("configuredMode");
|
||||||
QTest::addColumn<KWayland::Client::XdgDecoration::Mode>("configuredModeExp");
|
QTest::addColumn<KWayland::Client::XdgDecoration::Mode>("configuredModeExp");
|
||||||
QTest::addColumn<KWayland::Client::XdgDecoration::Mode>("setMode");
|
QTest::addColumn<KWayland::Client::XdgDecoration::Mode>("setMode");
|
||||||
QTest::addColumn<KWaylandServer::XdgDecorationInterface::Mode>("setModeExp");
|
QTest::addColumn<KWaylandServer::XdgToplevelDecorationV1Interface::Mode>("setModeExp");
|
||||||
|
|
||||||
const auto serverClient = XdgDecorationInterface::Mode::ClientSide;
|
const auto serverClient = XdgToplevelDecorationV1Interface::Mode::Client;
|
||||||
const auto serverServer = XdgDecorationInterface::Mode::ServerSide;
|
const auto serverServer = XdgToplevelDecorationV1Interface::Mode::Server;
|
||||||
const auto clientClient = XdgDecoration::Mode::ClientSide;
|
const auto clientClient = XdgDecoration::Mode::ClientSide;
|
||||||
const auto clientServer = XdgDecoration::Mode::ServerSide;
|
const auto clientServer = XdgDecoration::Mode::ServerSide;
|
||||||
|
|
||||||
|
@ -181,15 +177,14 @@ void TestXdgDecoration::testDecoration()
|
||||||
using namespace KWayland::Client;
|
using namespace KWayland::Client;
|
||||||
using namespace KWaylandServer;
|
using namespace KWaylandServer;
|
||||||
|
|
||||||
QFETCH(KWaylandServer::XdgDecorationInterface::Mode, configuredMode);
|
QFETCH(KWaylandServer::XdgToplevelDecorationV1Interface::Mode, configuredMode);
|
||||||
QFETCH(KWayland::Client::XdgDecoration::Mode, configuredModeExp);
|
QFETCH(KWayland::Client::XdgDecoration::Mode, configuredModeExp);
|
||||||
QFETCH(KWayland::Client::XdgDecoration::Mode, setMode);
|
QFETCH(KWayland::Client::XdgDecoration::Mode, setMode);
|
||||||
QFETCH(KWaylandServer::XdgDecorationInterface::Mode, setModeExp);
|
QFETCH(KWaylandServer::XdgToplevelDecorationV1Interface::Mode, setModeExp);
|
||||||
|
|
||||||
|
|
||||||
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
|
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
|
||||||
QSignalSpy shellSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
QSignalSpy shellSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::toplevelCreated);
|
||||||
QSignalSpy decorationCreatedSpy(m_xdgDecorationManagerInterface, &XdgDecorationManagerInterface::xdgDecorationInterfaceCreated);
|
QSignalSpy decorationCreatedSpy(m_xdgDecorationManagerInterface, &XdgDecorationManagerV1Interface::decorationCreated);
|
||||||
|
|
||||||
// create shell surface and deco object
|
// create shell surface and deco object
|
||||||
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
||||||
|
@ -201,20 +196,20 @@ void TestXdgDecoration::testDecoration()
|
||||||
QVERIFY(shellSurfaceCreatedSpy.count() || shellSurfaceCreatedSpy.wait());
|
QVERIFY(shellSurfaceCreatedSpy.count() || shellSurfaceCreatedSpy.wait());
|
||||||
QVERIFY(decorationCreatedSpy.count() || decorationCreatedSpy.wait());
|
QVERIFY(decorationCreatedSpy.count() || decorationCreatedSpy.wait());
|
||||||
|
|
||||||
auto shellSurfaceIface = shellSurfaceCreatedSpy.first().first().value<XdgShellSurfaceInterface*>();
|
auto shellSurfaceIface = shellSurfaceCreatedSpy.first().first().value<XdgToplevelInterface *>();
|
||||||
auto decorationIface = decorationCreatedSpy.first().first().value<XdgDecorationInterface*>();
|
auto decorationIface = decorationCreatedSpy.first().first().value<XdgToplevelDecorationV1Interface *>();
|
||||||
|
|
||||||
QVERIFY(decorationIface);
|
QVERIFY(decorationIface);
|
||||||
QVERIFY(shellSurfaceIface);
|
QVERIFY(shellSurfaceIface);
|
||||||
QCOMPARE(decorationIface->surface(), shellSurfaceIface);
|
QCOMPARE(decorationIface->toplevel(), shellSurfaceIface);
|
||||||
QCOMPARE(decorationIface->requestedMode(), XdgDecorationInterface::Mode::Undefined);
|
QCOMPARE(decorationIface->preferredMode(), XdgToplevelDecorationV1Interface::Mode::Undefined);
|
||||||
|
|
||||||
QSignalSpy clientConfiguredSpy(decoration.data(), &XdgDecoration::modeChanged);
|
QSignalSpy clientConfiguredSpy(decoration.data(), &XdgDecoration::modeChanged);
|
||||||
QSignalSpy modeRequestedSpy(decorationIface, &XdgDecorationInterface::modeRequested);
|
QSignalSpy modeRequestedSpy(decorationIface, &XdgToplevelDecorationV1Interface::preferredModeChanged);
|
||||||
|
|
||||||
//server configuring a client
|
//server configuring a client
|
||||||
decorationIface->configure(configuredMode);
|
decorationIface->sendConfigure(configuredMode);
|
||||||
quint32 serial = shellSurfaceIface->configure({});
|
quint32 serial = shellSurfaceIface->sendConfigure(QSize(0, 0), {});
|
||||||
QVERIFY(clientConfiguredSpy.wait());
|
QVERIFY(clientConfiguredSpy.wait());
|
||||||
QCOMPARE(clientConfiguredSpy.first().first().value<XdgDecoration::Mode>(), configuredModeExp);
|
QCOMPARE(clientConfiguredSpy.first().first().value<XdgDecoration::Mode>(), configuredModeExp);
|
||||||
|
|
||||||
|
@ -223,13 +218,14 @@ void TestXdgDecoration::testDecoration()
|
||||||
//client requesting another mode
|
//client requesting another mode
|
||||||
decoration->setMode(setMode);
|
decoration->setMode(setMode);
|
||||||
QVERIFY(modeRequestedSpy.wait());
|
QVERIFY(modeRequestedSpy.wait());
|
||||||
QCOMPARE(modeRequestedSpy.first().first().value<XdgDecorationInterface::Mode>(), setModeExp);
|
QCOMPARE(modeRequestedSpy.first().first().value<XdgToplevelDecorationV1Interface::Mode>(), setModeExp);
|
||||||
QCOMPARE(decorationIface->requestedMode(), setModeExp);
|
QCOMPARE(decorationIface->preferredMode(), setModeExp);
|
||||||
modeRequestedSpy.clear();
|
modeRequestedSpy.clear();
|
||||||
|
|
||||||
decoration->unsetMode();
|
decoration->unsetMode();
|
||||||
QVERIFY(modeRequestedSpy.wait());
|
QVERIFY(modeRequestedSpy.wait());
|
||||||
QCOMPARE(modeRequestedSpy.first().first().value<XdgDecorationInterface::Mode>(), XdgDecorationInterface::Mode::Undefined);
|
QCOMPARE(modeRequestedSpy.first().first().value<XdgToplevelDecorationV1Interface::Mode>(),
|
||||||
|
XdgToplevelDecorationV1Interface::Mode::Undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestXdgDecoration)
|
QTEST_GUILESS_MAIN(TestXdgDecoration)
|
||||||
|
|
|
@ -5,14 +5,86 @@
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "test_xdg_shell.h"
|
// Qt
|
||||||
|
#include <QtTest>
|
||||||
|
// client
|
||||||
|
#include "KWayland/Client/xdgshell.h"
|
||||||
|
#include "KWayland/Client/connection_thread.h"
|
||||||
|
#include "KWayland/Client/compositor.h"
|
||||||
|
#include "KWayland/Client/event_queue.h"
|
||||||
|
#include "KWayland/Client/registry.h"
|
||||||
|
#include "KWayland/Client/output.h"
|
||||||
|
#include "KWayland/Client/seat.h"
|
||||||
|
#include "KWayland/Client/shm_pool.h"
|
||||||
|
#include "KWayland/Client/surface.h"
|
||||||
|
// server
|
||||||
|
#include "../../src/server/display.h"
|
||||||
|
#include "../../src/server/compositor_interface.h"
|
||||||
|
#include "../../src/server/output_interface.h"
|
||||||
|
#include "../../src/server/seat_interface.h"
|
||||||
|
#include "../../src/server/surface_interface.h"
|
||||||
|
#include "../../src/server/xdgshell_interface.h"
|
||||||
|
|
||||||
XdgShellTest::XdgShellTest(XdgShellInterfaceVersion version):
|
using namespace KWayland::Client;
|
||||||
m_version(version)
|
using namespace KWaylandServer;
|
||||||
{}
|
|
||||||
|
Q_DECLARE_METATYPE(Qt::MouseButton)
|
||||||
|
|
||||||
static const QString s_socketName = QStringLiteral("kwayland-test-xdg_shell-0");
|
static const QString s_socketName = QStringLiteral("kwayland-test-xdg_shell-0");
|
||||||
|
|
||||||
|
class XdgShellTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void init();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
void testCreateSurface();
|
||||||
|
void testTitle();
|
||||||
|
void testWindowClass();
|
||||||
|
void testMaximize();
|
||||||
|
void testMinimize();
|
||||||
|
void testFullscreen();
|
||||||
|
void testShowWindowMenu();
|
||||||
|
void testMove();
|
||||||
|
void testResize_data();
|
||||||
|
void testResize();
|
||||||
|
void testTransient();
|
||||||
|
void testPing();
|
||||||
|
void testClose();
|
||||||
|
void testConfigureStates_data();
|
||||||
|
void testConfigureStates();
|
||||||
|
void testConfigureMultipleAcks();
|
||||||
|
|
||||||
|
private:
|
||||||
|
XdgShellInterface *m_xdgShellInterface = nullptr;
|
||||||
|
Compositor *m_compositor = nullptr;
|
||||||
|
XdgShell *m_xdgShell = nullptr;
|
||||||
|
Display *m_display = nullptr;
|
||||||
|
CompositorInterface *m_compositorInterface = nullptr;
|
||||||
|
OutputInterface *m_o1Interface = nullptr;
|
||||||
|
OutputInterface *m_o2Interface = nullptr;
|
||||||
|
SeatInterface *m_seatInterface = nullptr;
|
||||||
|
ConnectionThread *m_connection = nullptr;
|
||||||
|
QThread *m_thread = nullptr;
|
||||||
|
EventQueue *m_queue = nullptr;
|
||||||
|
ShmPool *m_shmPool = nullptr;
|
||||||
|
Output *m_output1 = nullptr;
|
||||||
|
Output *m_output2 = nullptr;
|
||||||
|
Seat *m_seat = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SURFACE \
|
||||||
|
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::toplevelCreated); \
|
||||||
|
QVERIFY(xdgSurfaceCreatedSpy.isValid()); \
|
||||||
|
QScopedPointer<Surface> surface(m_compositor->createSurface()); \
|
||||||
|
QScopedPointer<XdgShellSurface> xdgSurface(m_xdgShell->createSurface(surface.data())); \
|
||||||
|
QCOMPARE(xdgSurface->size(), QSize()); \
|
||||||
|
QVERIFY(xdgSurfaceCreatedSpy.wait()); \
|
||||||
|
auto serverXdgToplevel = xdgSurfaceCreatedSpy.first().first().value<XdgToplevelInterface *>(); \
|
||||||
|
QVERIFY(serverXdgToplevel);
|
||||||
|
|
||||||
void XdgShellTest::init()
|
void XdgShellTest::init()
|
||||||
{
|
{
|
||||||
delete m_display;
|
delete m_display;
|
||||||
|
@ -34,9 +106,7 @@ void XdgShellTest::init()
|
||||||
m_seatInterface->create();
|
m_seatInterface->create();
|
||||||
m_compositorInterface = m_display->createCompositor(m_display);
|
m_compositorInterface = m_display->createCompositor(m_display);
|
||||||
m_compositorInterface->create();
|
m_compositorInterface->create();
|
||||||
m_xdgShellInterface = m_display->createXdgShell(m_version, m_display);
|
m_xdgShellInterface = m_display->createXdgShell(m_display);
|
||||||
QCOMPARE(m_xdgShellInterface->interfaceVersion(), m_version);
|
|
||||||
m_xdgShellInterface->create();
|
|
||||||
|
|
||||||
// setup connection
|
// setup connection
|
||||||
m_connection = new KWayland::Client::ConnectionThread;
|
m_connection = new KWayland::Client::ConnectionThread;
|
||||||
|
@ -62,11 +132,7 @@ void XdgShellTest::init()
|
||||||
QSignalSpy outputAnnouncedSpy(®istry, &Registry::outputAnnounced);
|
QSignalSpy outputAnnouncedSpy(®istry, &Registry::outputAnnounced);
|
||||||
QVERIFY(outputAnnouncedSpy.isValid());
|
QVERIFY(outputAnnouncedSpy.isValid());
|
||||||
|
|
||||||
auto shellAnnouncedSignal = m_version == XdgShellInterfaceVersion::UnstableV5 ? &Registry::xdgShellUnstableV5Announced :
|
QSignalSpy xdgShellAnnouncedSpy(®istry, &Registry::xdgShellStableAnnounced);
|
||||||
m_version == XdgShellInterfaceVersion::UnstableV6 ? &Registry::xdgShellUnstableV6Announced :
|
|
||||||
&Registry::xdgShellStableAnnounced;
|
|
||||||
|
|
||||||
QSignalSpy xdgShellAnnouncedSpy(®istry, shellAnnouncedSignal);
|
|
||||||
QVERIFY(xdgShellAnnouncedSpy.isValid());
|
QVERIFY(xdgShellAnnouncedSpy.isValid());
|
||||||
registry.setEventQueue(m_queue);
|
registry.setEventQueue(m_queue);
|
||||||
registry.create(m_connection);
|
registry.create(m_connection);
|
||||||
|
@ -92,21 +158,8 @@ void XdgShellTest::init()
|
||||||
|
|
||||||
QCOMPARE(xdgShellAnnouncedSpy.count(), 1);
|
QCOMPARE(xdgShellAnnouncedSpy.count(), 1);
|
||||||
|
|
||||||
Registry::Interface iface;
|
m_xdgShell = registry.createXdgShell(registry.interface(Registry::Interface::XdgShellStable).name,
|
||||||
switch (m_version) {
|
registry.interface(Registry::Interface::XdgShellStable).version,
|
||||||
case XdgShellInterfaceVersion::UnstableV5:
|
|
||||||
iface = Registry::Interface::XdgShellUnstableV5;
|
|
||||||
break;
|
|
||||||
case XdgShellInterfaceVersion::UnstableV6:
|
|
||||||
iface = Registry::Interface::XdgShellUnstableV6;
|
|
||||||
break;
|
|
||||||
case XdgShellInterfaceVersion::Stable:
|
|
||||||
iface = Registry::Interface::XdgShellStable;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_xdgShell = registry.createXdgShell(registry.interface(iface).name,
|
|
||||||
registry.interface(iface).version,
|
|
||||||
this);
|
this);
|
||||||
QVERIFY(m_xdgShell);
|
QVERIFY(m_xdgShell);
|
||||||
QVERIFY(m_xdgShell->isValid());
|
QVERIFY(m_xdgShell->isValid());
|
||||||
|
@ -152,7 +205,7 @@ void XdgShellTest::testCreateSurface()
|
||||||
// first created the signal spies for the server
|
// first created the signal spies for the server
|
||||||
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
|
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
|
||||||
QVERIFY(surfaceCreatedSpy.isValid());
|
QVERIFY(surfaceCreatedSpy.isValid());
|
||||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::toplevelCreated);
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.isValid());
|
QVERIFY(xdgSurfaceCreatedSpy.isValid());
|
||||||
|
|
||||||
// create surface
|
// create surface
|
||||||
|
@ -167,17 +220,15 @@ void XdgShellTest::testCreateSurface()
|
||||||
QVERIFY(!xdgSurface.isNull());
|
QVERIFY(!xdgSurface.isNull());
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
||||||
// verify base things
|
// verify base things
|
||||||
auto serverXdgSurface = xdgSurfaceCreatedSpy.first().first().value<XdgShellSurfaceInterface*>();
|
auto serverToplevel = xdgSurfaceCreatedSpy.first().first().value<XdgToplevelInterface *>();
|
||||||
QVERIFY(serverXdgSurface);
|
QVERIFY(serverToplevel);
|
||||||
QCOMPARE(serverXdgSurface->isConfigurePending(), false);
|
QCOMPARE(serverToplevel->windowTitle(), QString());
|
||||||
QCOMPARE(serverXdgSurface->title(), QString());
|
QCOMPARE(serverToplevel->windowClass(), QByteArray());
|
||||||
QCOMPARE(serverXdgSurface->windowClass(), QByteArray());
|
QCOMPARE(serverToplevel->parentXdgToplevel(), nullptr);
|
||||||
QCOMPARE(serverXdgSurface->isTransient(), false);
|
QCOMPARE(serverToplevel->surface(), serverSurface);
|
||||||
QCOMPARE(serverXdgSurface->transientFor(), QPointer<XdgShellSurfaceInterface>());
|
|
||||||
QCOMPARE(serverXdgSurface->surface(), serverSurface);
|
|
||||||
|
|
||||||
// now let's destroy it
|
// now let's destroy it
|
||||||
QSignalSpy destroyedSpy(serverXdgSurface, &QObject::destroyed);
|
QSignalSpy destroyedSpy(serverToplevel, &QObject::destroyed);
|
||||||
QVERIFY(destroyedSpy.isValid());
|
QVERIFY(destroyedSpy.isValid());
|
||||||
xdgSurface.reset();
|
xdgSurface.reset();
|
||||||
QVERIFY(destroyedSpy.wait());
|
QVERIFY(destroyedSpy.wait());
|
||||||
|
@ -190,16 +241,16 @@ void XdgShellTest::testTitle()
|
||||||
SURFACE
|
SURFACE
|
||||||
|
|
||||||
// should not have a title yet
|
// should not have a title yet
|
||||||
QCOMPARE(serverXdgSurface->title(), QString());
|
QCOMPARE(serverXdgToplevel->windowTitle(), QString());
|
||||||
|
|
||||||
// lets' change the title
|
// lets' change the title
|
||||||
QSignalSpy titleChangedSpy(serverXdgSurface, &XdgShellSurfaceInterface::titleChanged);
|
QSignalSpy titleChangedSpy(serverXdgToplevel, &XdgToplevelInterface::windowTitleChanged);
|
||||||
QVERIFY(titleChangedSpy.isValid());
|
QVERIFY(titleChangedSpy.isValid());
|
||||||
xdgSurface->setTitle(QStringLiteral("foo"));
|
xdgSurface->setTitle(QStringLiteral("foo"));
|
||||||
QVERIFY(titleChangedSpy.wait());
|
QVERIFY(titleChangedSpy.wait());
|
||||||
QCOMPARE(titleChangedSpy.count(), 1);
|
QCOMPARE(titleChangedSpy.count(), 1);
|
||||||
QCOMPARE(titleChangedSpy.first().first().toString(), QStringLiteral("foo"));
|
QCOMPARE(titleChangedSpy.first().first().toString(), QStringLiteral("foo"));
|
||||||
QCOMPARE(serverXdgSurface->title(), QStringLiteral("foo"));
|
QCOMPARE(serverXdgToplevel->windowTitle(), QStringLiteral("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XdgShellTest::testWindowClass()
|
void XdgShellTest::testWindowClass()
|
||||||
|
@ -209,16 +260,16 @@ void XdgShellTest::testWindowClass()
|
||||||
SURFACE
|
SURFACE
|
||||||
|
|
||||||
// should not have a window class yet
|
// should not have a window class yet
|
||||||
QCOMPARE(serverXdgSurface->windowClass(), QByteArray());
|
QCOMPARE(serverXdgToplevel->windowClass(), QByteArray());
|
||||||
|
|
||||||
// let's change the window class
|
// let's change the window class
|
||||||
QSignalSpy windowClassChanged(serverXdgSurface, &XdgShellSurfaceInterface::windowClassChanged);
|
QSignalSpy windowClassChanged(serverXdgToplevel, &XdgToplevelInterface::windowClassChanged);
|
||||||
QVERIFY(windowClassChanged.isValid());
|
QVERIFY(windowClassChanged.isValid());
|
||||||
xdgSurface->setAppId(QByteArrayLiteral("org.kde.xdgsurfacetest"));
|
xdgSurface->setAppId(QByteArrayLiteral("org.kde.xdgsurfacetest"));
|
||||||
QVERIFY(windowClassChanged.wait());
|
QVERIFY(windowClassChanged.wait());
|
||||||
QCOMPARE(windowClassChanged.count(), 1);
|
QCOMPARE(windowClassChanged.count(), 1);
|
||||||
QCOMPARE(windowClassChanged.first().first().toByteArray(), QByteArrayLiteral("org.kde.xdgsurfacetest"));
|
QCOMPARE(windowClassChanged.first().first().toByteArray(), QByteArrayLiteral("org.kde.xdgsurfacetest"));
|
||||||
QCOMPARE(serverXdgSurface->windowClass(), QByteArrayLiteral("org.kde.xdgsurfacetest"));
|
QCOMPARE(serverXdgToplevel->windowClass(), QByteArrayLiteral("org.kde.xdgsurfacetest"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XdgShellTest::testMaximize()
|
void XdgShellTest::testMaximize()
|
||||||
|
@ -226,18 +277,18 @@ void XdgShellTest::testMaximize()
|
||||||
// this test verifies that the maximize/unmaximize calls work
|
// this test verifies that the maximize/unmaximize calls work
|
||||||
SURFACE
|
SURFACE
|
||||||
|
|
||||||
QSignalSpy maximizeRequestedSpy(serverXdgSurface, &XdgShellSurfaceInterface::maximizedChanged);
|
QSignalSpy maximizeRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::maximizeRequested);
|
||||||
QVERIFY(maximizeRequestedSpy.isValid());
|
QVERIFY(maximizeRequestedSpy.isValid());
|
||||||
|
QSignalSpy unmaximizeRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::unmaximizeRequested);
|
||||||
|
QVERIFY(unmaximizeRequestedSpy.isValid());
|
||||||
|
|
||||||
xdgSurface->setMaximized(true);
|
xdgSurface->setMaximized(true);
|
||||||
QVERIFY(maximizeRequestedSpy.wait());
|
QVERIFY(maximizeRequestedSpy.wait());
|
||||||
QCOMPARE(maximizeRequestedSpy.count(), 1);
|
QCOMPARE(maximizeRequestedSpy.count(), 1);
|
||||||
QCOMPARE(maximizeRequestedSpy.last().first().toBool(), true);
|
|
||||||
|
|
||||||
xdgSurface->setMaximized(false);
|
xdgSurface->setMaximized(false);
|
||||||
QVERIFY(maximizeRequestedSpy.wait());
|
QVERIFY(unmaximizeRequestedSpy.wait());
|
||||||
QCOMPARE(maximizeRequestedSpy.count(), 2);
|
QCOMPARE(unmaximizeRequestedSpy.count(), 1);
|
||||||
QCOMPARE(maximizeRequestedSpy.last().first().toBool(), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XdgShellTest::testMinimize()
|
void XdgShellTest::testMinimize()
|
||||||
|
@ -245,7 +296,7 @@ void XdgShellTest::testMinimize()
|
||||||
// this test verifies that the minimize request is delivered
|
// this test verifies that the minimize request is delivered
|
||||||
SURFACE
|
SURFACE
|
||||||
|
|
||||||
QSignalSpy minimizeRequestedSpy(serverXdgSurface, &XdgShellSurfaceInterface::minimizeRequested);
|
QSignalSpy minimizeRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::minimizeRequested);
|
||||||
QVERIFY(minimizeRequestedSpy.isValid());
|
QVERIFY(minimizeRequestedSpy.isValid());
|
||||||
|
|
||||||
xdgSurface->requestMinimize();
|
xdgSurface->requestMinimize();
|
||||||
|
@ -257,44 +308,35 @@ void XdgShellTest::testFullscreen()
|
||||||
{
|
{
|
||||||
qRegisterMetaType<OutputInterface*>();
|
qRegisterMetaType<OutputInterface*>();
|
||||||
// this test verifies going to/from fullscreen
|
// this test verifies going to/from fullscreen
|
||||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
SURFACE
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.isValid());
|
|
||||||
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
|
||||||
QScopedPointer<XdgShellSurface> xdgSurface(m_xdgShell->createSurface(surface.data()));
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
|
||||||
auto serverXdgSurface = xdgSurfaceCreatedSpy.first().first().value<XdgShellSurfaceInterface*>();
|
|
||||||
QVERIFY(serverXdgSurface);
|
|
||||||
|
|
||||||
QSignalSpy fullscreenSpy(serverXdgSurface, &XdgShellSurfaceInterface::fullscreenChanged);
|
QSignalSpy fullscreenRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::fullscreenRequested);
|
||||||
QVERIFY(fullscreenSpy.isValid());
|
QVERIFY(fullscreenRequestedSpy.isValid());
|
||||||
|
QSignalSpy unfullscreenRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::unfullscreenRequested);
|
||||||
|
QVERIFY(fullscreenRequestedSpy.isValid());
|
||||||
|
|
||||||
// without an output
|
// without an output
|
||||||
xdgSurface->setFullscreen(true, nullptr);
|
xdgSurface->setFullscreen(true, nullptr);
|
||||||
QVERIFY(fullscreenSpy.wait());
|
QVERIFY(fullscreenRequestedSpy.wait());
|
||||||
QCOMPARE(fullscreenSpy.count(), 1);
|
QCOMPARE(fullscreenRequestedSpy.count(), 1);
|
||||||
QCOMPARE(fullscreenSpy.last().at(0).toBool(), true);
|
QVERIFY(!fullscreenRequestedSpy.last().at(0).value<OutputInterface*>());
|
||||||
QVERIFY(!fullscreenSpy.last().at(1).value<OutputInterface*>());
|
|
||||||
|
|
||||||
// unset
|
// unset
|
||||||
xdgSurface->setFullscreen(false);
|
xdgSurface->setFullscreen(false);
|
||||||
QVERIFY(fullscreenSpy.wait());
|
QVERIFY(unfullscreenRequestedSpy.wait());
|
||||||
QCOMPARE(fullscreenSpy.count(), 2);
|
QCOMPARE(unfullscreenRequestedSpy.count(), 1);
|
||||||
QCOMPARE(fullscreenSpy.last().at(0).toBool(), false);
|
|
||||||
QVERIFY(!fullscreenSpy.last().at(1).value<OutputInterface*>());
|
|
||||||
|
|
||||||
// with outputs
|
// with outputs
|
||||||
xdgSurface->setFullscreen(true, m_output1);
|
xdgSurface->setFullscreen(true, m_output1);
|
||||||
QVERIFY(fullscreenSpy.wait());
|
QVERIFY(fullscreenRequestedSpy.wait());
|
||||||
QCOMPARE(fullscreenSpy.count(), 3);
|
QCOMPARE(fullscreenRequestedSpy.count(), 2);
|
||||||
QCOMPARE(fullscreenSpy.last().at(0).toBool(), true);
|
QCOMPARE(fullscreenRequestedSpy.last().at(0).value<OutputInterface*>(), m_o1Interface);
|
||||||
QCOMPARE(fullscreenSpy.last().at(1).value<OutputInterface*>(), m_o1Interface);
|
|
||||||
|
|
||||||
// now other output
|
// now other output
|
||||||
xdgSurface->setFullscreen(true, m_output2);
|
xdgSurface->setFullscreen(true, m_output2);
|
||||||
QVERIFY(fullscreenSpy.wait());
|
QVERIFY(fullscreenRequestedSpy.wait());
|
||||||
QCOMPARE(fullscreenSpy.count(), 4);
|
QCOMPARE(fullscreenRequestedSpy.count(), 3);
|
||||||
QCOMPARE(fullscreenSpy.last().at(0).toBool(), true);
|
QCOMPARE(fullscreenRequestedSpy.last().at(0).value<OutputInterface*>(), m_o2Interface);
|
||||||
QCOMPARE(fullscreenSpy.last().at(1).value<OutputInterface*>(), m_o2Interface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XdgShellTest::testShowWindowMenu()
|
void XdgShellTest::testShowWindowMenu()
|
||||||
|
@ -303,7 +345,10 @@ void XdgShellTest::testShowWindowMenu()
|
||||||
// this test verifies that the show window menu request works
|
// this test verifies that the show window menu request works
|
||||||
SURFACE
|
SURFACE
|
||||||
|
|
||||||
QSignalSpy windowMenuSpy(serverXdgSurface, &XdgShellSurfaceInterface::windowMenuRequested);
|
// hack: pretend that the xdg-surface had been configured
|
||||||
|
serverXdgToplevel->sendConfigure(QSize(0, 0), XdgToplevelInterface::States());
|
||||||
|
|
||||||
|
QSignalSpy windowMenuSpy(serverXdgToplevel, &XdgToplevelInterface::windowMenuRequested);
|
||||||
QVERIFY(windowMenuSpy.isValid());
|
QVERIFY(windowMenuSpy.isValid());
|
||||||
|
|
||||||
// TODO: the serial needs to be a proper one
|
// TODO: the serial needs to be a proper one
|
||||||
|
@ -311,8 +356,8 @@ void XdgShellTest::testShowWindowMenu()
|
||||||
QVERIFY(windowMenuSpy.wait());
|
QVERIFY(windowMenuSpy.wait());
|
||||||
QCOMPARE(windowMenuSpy.count(), 1);
|
QCOMPARE(windowMenuSpy.count(), 1);
|
||||||
QCOMPARE(windowMenuSpy.first().at(0).value<SeatInterface*>(), m_seatInterface);
|
QCOMPARE(windowMenuSpy.first().at(0).value<SeatInterface*>(), m_seatInterface);
|
||||||
QCOMPARE(windowMenuSpy.first().at(1).value<quint32>(), 20u);
|
QCOMPARE(windowMenuSpy.first().at(1).toPoint(), QPoint(30, 40));
|
||||||
QCOMPARE(windowMenuSpy.first().at(2).toPoint(), QPoint(30, 40));
|
QCOMPARE(windowMenuSpy.first().at(2).value<quint32>(), 20u);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XdgShellTest::testMove()
|
void XdgShellTest::testMove()
|
||||||
|
@ -321,7 +366,10 @@ void XdgShellTest::testMove()
|
||||||
// this test verifies that the move request works
|
// this test verifies that the move request works
|
||||||
SURFACE
|
SURFACE
|
||||||
|
|
||||||
QSignalSpy moveSpy(serverXdgSurface, &XdgShellSurfaceInterface::moveRequested);
|
// hack: pretend that the xdg-surface had been configured
|
||||||
|
serverXdgToplevel->sendConfigure(QSize(0, 0), XdgToplevelInterface::States());
|
||||||
|
|
||||||
|
QSignalSpy moveSpy(serverXdgToplevel, &XdgToplevelInterface::moveRequested);
|
||||||
QVERIFY(moveSpy.isValid());
|
QVERIFY(moveSpy.isValid());
|
||||||
|
|
||||||
// TODO: the serial needs to be a proper one
|
// TODO: the serial needs to be a proper one
|
||||||
|
@ -353,7 +401,10 @@ void XdgShellTest::testResize()
|
||||||
// this test verifies that the resize request works
|
// this test verifies that the resize request works
|
||||||
SURFACE
|
SURFACE
|
||||||
|
|
||||||
QSignalSpy resizeSpy(serverXdgSurface, &XdgShellSurfaceInterface::resizeRequested);
|
// hack: pretend that the xdg-surface had been configured
|
||||||
|
serverXdgToplevel->sendConfigure(QSize(0, 0), XdgToplevelInterface::States());
|
||||||
|
|
||||||
|
QSignalSpy resizeSpy(serverXdgToplevel, &XdgToplevelInterface::resizeRequested);
|
||||||
QVERIFY(resizeSpy.isValid());
|
QVERIFY(resizeSpy.isValid());
|
||||||
|
|
||||||
// TODO: the serial needs to be a proper one
|
// TODO: the serial needs to be a proper one
|
||||||
|
@ -362,8 +413,8 @@ void XdgShellTest::testResize()
|
||||||
QVERIFY(resizeSpy.wait());
|
QVERIFY(resizeSpy.wait());
|
||||||
QCOMPARE(resizeSpy.count(), 1);
|
QCOMPARE(resizeSpy.count(), 1);
|
||||||
QCOMPARE(resizeSpy.first().at(0).value<SeatInterface*>(), m_seatInterface);
|
QCOMPARE(resizeSpy.first().at(0).value<SeatInterface*>(), m_seatInterface);
|
||||||
QCOMPARE(resizeSpy.first().at(1).value<quint32>(), 60u);
|
QCOMPARE(resizeSpy.first().at(1).value<Qt::Edges>(), edges);
|
||||||
QCOMPARE(resizeSpy.first().at(2).value<Qt::Edges>(), edges);
|
QCOMPARE(resizeSpy.first().at(2).value<quint32>(), 60u);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XdgShellTest::testTransient()
|
void XdgShellTest::testTransient()
|
||||||
|
@ -373,30 +424,28 @@ void XdgShellTest::testTransient()
|
||||||
QScopedPointer<Surface> surface2(m_compositor->createSurface());
|
QScopedPointer<Surface> surface2(m_compositor->createSurface());
|
||||||
QScopedPointer<XdgShellSurface> xdgSurface2(m_xdgShell->createSurface(surface2.data()));
|
QScopedPointer<XdgShellSurface> xdgSurface2(m_xdgShell->createSurface(surface2.data()));
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
||||||
auto serverXdgSurface2 = xdgSurfaceCreatedSpy.last().first().value<XdgShellSurfaceInterface*>();
|
auto serverXdgToplevel2 = xdgSurfaceCreatedSpy.last().first().value<XdgToplevelInterface *>();
|
||||||
QVERIFY(serverXdgSurface2);
|
QVERIFY(serverXdgToplevel2);
|
||||||
|
|
||||||
QVERIFY(!serverXdgSurface->isTransient());
|
QVERIFY(!serverXdgToplevel->parentXdgToplevel());
|
||||||
QVERIFY(!serverXdgSurface2->isTransient());
|
QVERIFY(!serverXdgToplevel2->parentXdgToplevel());
|
||||||
|
|
||||||
// now make xdsgSurface2 a transient for xdgSurface
|
// now make xdsgSurface2 a transient for xdgSurface
|
||||||
QSignalSpy transientForSpy(serverXdgSurface2, &XdgShellSurfaceInterface::transientForChanged);
|
QSignalSpy transientForSpy(serverXdgToplevel2, &XdgToplevelInterface::parentXdgToplevelChanged);
|
||||||
QVERIFY(transientForSpy.isValid());
|
QVERIFY(transientForSpy.isValid());
|
||||||
xdgSurface2->setTransientFor(xdgSurface.data());
|
xdgSurface2->setTransientFor(xdgSurface.data());
|
||||||
|
|
||||||
QVERIFY(transientForSpy.wait());
|
QVERIFY(transientForSpy.wait());
|
||||||
QCOMPARE(transientForSpy.count(), 1);
|
QCOMPARE(transientForSpy.count(), 1);
|
||||||
QVERIFY(serverXdgSurface2->isTransient());
|
QCOMPARE(serverXdgToplevel2->parentXdgToplevel(), serverXdgToplevel);
|
||||||
QCOMPARE(serverXdgSurface2->transientFor().data(), serverXdgSurface);
|
QVERIFY(!serverXdgToplevel->parentXdgToplevel());
|
||||||
QVERIFY(!serverXdgSurface->isTransient());
|
|
||||||
|
|
||||||
// unset the transient for
|
// unset the transient for
|
||||||
xdgSurface2->setTransientFor(nullptr);
|
xdgSurface2->setTransientFor(nullptr);
|
||||||
QVERIFY(transientForSpy.wait());
|
QVERIFY(transientForSpy.wait());
|
||||||
QCOMPARE(transientForSpy.count(), 2);
|
QCOMPARE(transientForSpy.count(), 2);
|
||||||
QVERIFY(!serverXdgSurface2->isTransient());
|
QVERIFY(!serverXdgToplevel2->parentXdgToplevel());
|
||||||
QVERIFY(serverXdgSurface2->transientFor().isNull());
|
QVERIFY(!serverXdgToplevel->parentXdgToplevel());
|
||||||
QVERIFY(!serverXdgSurface->isTransient());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XdgShellTest::testPing()
|
void XdgShellTest::testPing()
|
||||||
|
@ -407,7 +456,7 @@ void XdgShellTest::testPing()
|
||||||
QSignalSpy pingSpy(m_xdgShellInterface, &XdgShellInterface::pongReceived);
|
QSignalSpy pingSpy(m_xdgShellInterface, &XdgShellInterface::pongReceived);
|
||||||
QVERIFY(pingSpy.isValid());
|
QVERIFY(pingSpy.isValid());
|
||||||
|
|
||||||
quint32 serial = m_xdgShellInterface->ping(serverXdgSurface);
|
quint32 serial = m_xdgShellInterface->ping(serverXdgToplevel->xdgSurface());
|
||||||
QVERIFY(pingSpy.wait());
|
QVERIFY(pingSpy.wait());
|
||||||
QCOMPARE(pingSpy.count(), 1);
|
QCOMPARE(pingSpy.count(), 1);
|
||||||
QCOMPARE(pingSpy.takeFirst().at(0).value<quint32>(), serial);
|
QCOMPARE(pingSpy.takeFirst().at(0).value<quint32>(), serial);
|
||||||
|
@ -415,7 +464,7 @@ void XdgShellTest::testPing()
|
||||||
// test of a ping failure
|
// test of a ping failure
|
||||||
// disconnecting the connection thread to the queue will break the connection and pings will do a timeout
|
// disconnecting the connection thread to the queue will break the connection and pings will do a timeout
|
||||||
disconnect(m_connection, &ConnectionThread::eventsRead, m_queue, &EventQueue::dispatch);
|
disconnect(m_connection, &ConnectionThread::eventsRead, m_queue, &EventQueue::dispatch);
|
||||||
m_xdgShellInterface->ping(serverXdgSurface);
|
m_xdgShellInterface->ping(serverXdgToplevel->xdgSurface());
|
||||||
QSignalSpy pingDelayedSpy(m_xdgShellInterface, &XdgShellInterface::pingDelayed);
|
QSignalSpy pingDelayedSpy(m_xdgShellInterface, &XdgShellInterface::pingDelayed);
|
||||||
QVERIFY(pingDelayedSpy.wait());
|
QVERIFY(pingDelayedSpy.wait());
|
||||||
|
|
||||||
|
@ -431,11 +480,11 @@ void XdgShellTest::testClose()
|
||||||
QSignalSpy closeSpy(xdgSurface.data(), &XdgShellSurface::closeRequested);
|
QSignalSpy closeSpy(xdgSurface.data(), &XdgShellSurface::closeRequested);
|
||||||
QVERIFY(closeSpy.isValid());
|
QVERIFY(closeSpy.isValid());
|
||||||
|
|
||||||
serverXdgSurface->close();
|
serverXdgToplevel->sendClose();
|
||||||
QVERIFY(closeSpy.wait());
|
QVERIFY(closeSpy.wait());
|
||||||
QCOMPARE(closeSpy.count(), 1);
|
QCOMPARE(closeSpy.count(), 1);
|
||||||
|
|
||||||
QSignalSpy destroyedSpy(serverXdgSurface, &XdgShellSurfaceInterface::destroyed);
|
QSignalSpy destroyedSpy(serverXdgToplevel, &XdgToplevelInterface::destroyed);
|
||||||
QVERIFY(destroyedSpy.isValid());
|
QVERIFY(destroyedSpy.isValid());
|
||||||
xdgSurface.reset();
|
xdgSurface.reset();
|
||||||
QVERIFY(destroyedSpy.wait());
|
QVERIFY(destroyedSpy.wait());
|
||||||
|
@ -443,20 +492,20 @@ void XdgShellTest::testClose()
|
||||||
|
|
||||||
void XdgShellTest::testConfigureStates_data()
|
void XdgShellTest::testConfigureStates_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<XdgShellSurfaceInterface::States>("serverStates");
|
QTest::addColumn<XdgToplevelInterface::States>("serverStates");
|
||||||
QTest::addColumn<XdgShellSurface::States>("clientStates");
|
QTest::addColumn<XdgShellSurface::States>("clientStates");
|
||||||
|
|
||||||
const auto sa = XdgShellSurfaceInterface::States(XdgShellSurfaceInterface::State::Activated);
|
const auto sa = XdgToplevelInterface::States(XdgToplevelInterface::State::Activated);
|
||||||
const auto sm = XdgShellSurfaceInterface::States(XdgShellSurfaceInterface::State::Maximized);
|
const auto sm = XdgToplevelInterface::States(XdgToplevelInterface::State::Maximized);
|
||||||
const auto sf = XdgShellSurfaceInterface::States(XdgShellSurfaceInterface::State::Fullscreen);
|
const auto sf = XdgToplevelInterface::States(XdgToplevelInterface::State::FullScreen);
|
||||||
const auto sr = XdgShellSurfaceInterface::States(XdgShellSurfaceInterface::State::Resizing);
|
const auto sr = XdgToplevelInterface::States(XdgToplevelInterface::State::Resizing);
|
||||||
|
|
||||||
const auto ca = XdgShellSurface::States(XdgShellSurface::State::Activated);
|
const auto ca = XdgShellSurface::States(XdgShellSurface::State::Activated);
|
||||||
const auto cm = XdgShellSurface::States(XdgShellSurface::State::Maximized);
|
const auto cm = XdgShellSurface::States(XdgShellSurface::State::Maximized);
|
||||||
const auto cf = XdgShellSurface::States(XdgShellSurface::State::Fullscreen);
|
const auto cf = XdgShellSurface::States(XdgShellSurface::State::Fullscreen);
|
||||||
const auto cr = XdgShellSurface::States(XdgShellSurface::State::Resizing);
|
const auto cr = XdgShellSurface::States(XdgShellSurface::State::Resizing);
|
||||||
|
|
||||||
QTest::newRow("none") << XdgShellSurfaceInterface::States() << XdgShellSurface::States();
|
QTest::newRow("none") << XdgToplevelInterface::States() << XdgShellSurface::States();
|
||||||
QTest::newRow("Active") << sa << ca;
|
QTest::newRow("Active") << sa << ca;
|
||||||
QTest::newRow("Maximize") << sm << cm;
|
QTest::newRow("Maximize") << sm << cm;
|
||||||
QTest::newRow("Fullscreen") << sf << cf;
|
QTest::newRow("Fullscreen") << sf << cf;
|
||||||
|
@ -485,15 +534,15 @@ void XdgShellTest::testConfigureStates()
|
||||||
QSignalSpy configureSpy(xdgSurface.data(), &XdgShellSurface::configureRequested);
|
QSignalSpy configureSpy(xdgSurface.data(), &XdgShellSurface::configureRequested);
|
||||||
QVERIFY(configureSpy.isValid());
|
QVERIFY(configureSpy.isValid());
|
||||||
|
|
||||||
QFETCH(XdgShellSurfaceInterface::States, serverStates);
|
QFETCH(XdgToplevelInterface::States, serverStates);
|
||||||
serverXdgSurface->configure(serverStates);
|
serverXdgToplevel->sendConfigure(QSize(0, 0), serverStates);
|
||||||
QVERIFY(configureSpy.wait());
|
QVERIFY(configureSpy.wait());
|
||||||
QCOMPARE(configureSpy.count(), 1);
|
QCOMPARE(configureSpy.count(), 1);
|
||||||
QCOMPARE(configureSpy.first().at(0).toSize(), QSize(0, 0));
|
QCOMPARE(configureSpy.first().at(0).toSize(), QSize(0, 0));
|
||||||
QTEST(configureSpy.first().at(1).value<XdgShellSurface::States>(), "clientStates");
|
QTEST(configureSpy.first().at(1).value<XdgShellSurface::States>(), "clientStates");
|
||||||
QCOMPARE(configureSpy.first().at(2).value<quint32>(), m_display->serial());
|
QCOMPARE(configureSpy.first().at(2).value<quint32>(), m_display->serial());
|
||||||
|
|
||||||
QSignalSpy ackSpy(serverXdgSurface, &XdgShellSurfaceInterface::configureAcknowledged);
|
QSignalSpy ackSpy(serverXdgToplevel->xdgSurface(), &XdgSurfaceInterface::configureAcknowledged);
|
||||||
QVERIFY(ackSpy.isValid());
|
QVERIFY(ackSpy.isValid());
|
||||||
|
|
||||||
xdgSurface->ackConfigure(configureSpy.first().at(2).value<quint32>());
|
xdgSurface->ackConfigure(configureSpy.first().at(2).value<quint32>());
|
||||||
|
@ -512,15 +561,15 @@ void XdgShellTest::testConfigureMultipleAcks()
|
||||||
QVERIFY(configureSpy.isValid());
|
QVERIFY(configureSpy.isValid());
|
||||||
QSignalSpy sizeChangedSpy(xdgSurface.data(), &XdgShellSurface::sizeChanged);
|
QSignalSpy sizeChangedSpy(xdgSurface.data(), &XdgShellSurface::sizeChanged);
|
||||||
QVERIFY(sizeChangedSpy.isValid());
|
QVERIFY(sizeChangedSpy.isValid());
|
||||||
QSignalSpy ackSpy(serverXdgSurface, &XdgShellSurfaceInterface::configureAcknowledged);
|
QSignalSpy ackSpy(serverXdgToplevel->xdgSurface(), &XdgSurfaceInterface::configureAcknowledged);
|
||||||
QVERIFY(ackSpy.isValid());
|
QVERIFY(ackSpy.isValid());
|
||||||
|
|
||||||
serverXdgSurface->configure(XdgShellSurfaceInterface::States(), QSize(10, 20));
|
serverXdgToplevel->sendConfigure(QSize(10, 20), XdgToplevelInterface::States());
|
||||||
const quint32 serial1 = m_display->serial();
|
const quint32 serial1 = m_display->serial();
|
||||||
serverXdgSurface->configure(XdgShellSurfaceInterface::States(), QSize(20, 30));
|
serverXdgToplevel->sendConfigure(QSize(20, 30), XdgToplevelInterface::States());
|
||||||
const quint32 serial2 = m_display->serial();
|
const quint32 serial2 = m_display->serial();
|
||||||
QVERIFY(serial1 != serial2);
|
QVERIFY(serial1 != serial2);
|
||||||
serverXdgSurface->configure(XdgShellSurfaceInterface::States(), QSize(30, 40));
|
serverXdgToplevel->sendConfigure(QSize(30, 40), XdgToplevelInterface::States());
|
||||||
const quint32 serial3 = m_display->serial();
|
const quint32 serial3 = m_display->serial();
|
||||||
QVERIFY(serial1 != serial3);
|
QVERIFY(serial1 != serial3);
|
||||||
QVERIFY(serial2 != serial3);
|
QVERIFY(serial2 != serial3);
|
||||||
|
@ -544,16 +593,17 @@ void XdgShellTest::testConfigureMultipleAcks()
|
||||||
|
|
||||||
xdgSurface->ackConfigure(serial3);
|
xdgSurface->ackConfigure(serial3);
|
||||||
QVERIFY(ackSpy.wait());
|
QVERIFY(ackSpy.wait());
|
||||||
QCOMPARE(ackSpy.count(), 3);
|
QCOMPARE(ackSpy.count(), 1);
|
||||||
QCOMPARE(ackSpy.at(0).first().value<quint32>(), serial1);
|
QCOMPARE(ackSpy.last().first().value<quint32>(), serial3);
|
||||||
QCOMPARE(ackSpy.at(1).first().value<quint32>(), serial2);
|
|
||||||
QCOMPARE(ackSpy.at(2).first().value<quint32>(), serial3);
|
|
||||||
|
|
||||||
// configure once more with a null size
|
// configure once more with a null size
|
||||||
serverXdgSurface->configure(XdgShellSurfaceInterface::States());
|
serverXdgToplevel->sendConfigure(QSize(0, 0), XdgToplevelInterface::States());
|
||||||
// should not change size
|
// should not change size
|
||||||
QVERIFY(configureSpy.wait());
|
QVERIFY(configureSpy.wait());
|
||||||
QCOMPARE(configureSpy.count(), 4);
|
QCOMPARE(configureSpy.count(), 4);
|
||||||
QCOMPARE(sizeChangedSpy.count(), 3);
|
QCOMPARE(sizeChangedSpy.count(), 3);
|
||||||
QCOMPARE(xdgSurface->size(), QSize(30, 40));
|
QCOMPARE(xdgSurface->size(), QSize(30, 40));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(XdgShellTest)
|
||||||
|
#include "test_xdg_shell.moc"
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
||||||
*/
|
|
||||||
#ifndef TEST_XDG_SHELL_H
|
|
||||||
#define TEST_XDG_SHELL_H
|
|
||||||
|
|
||||||
// Qt
|
|
||||||
#include <QtTest>
|
|
||||||
// client
|
|
||||||
#include "KWayland/Client/xdgshell.h"
|
|
||||||
#include "KWayland/Client/connection_thread.h"
|
|
||||||
#include "KWayland/Client/compositor.h"
|
|
||||||
#include "KWayland/Client/event_queue.h"
|
|
||||||
#include "KWayland/Client/registry.h"
|
|
||||||
#include "KWayland/Client/output.h"
|
|
||||||
#include "KWayland/Client/seat.h"
|
|
||||||
#include "KWayland/Client/shm_pool.h"
|
|
||||||
#include "KWayland/Client/surface.h"
|
|
||||||
// server
|
|
||||||
#include "../../src/server/display.h"
|
|
||||||
#include "../../src/server/compositor_interface.h"
|
|
||||||
#include "../../src/server/output_interface.h"
|
|
||||||
#include "../../src/server/seat_interface.h"
|
|
||||||
#include "../../src/server/surface_interface.h"
|
|
||||||
#include "../../src/server/xdgshell_interface.h"
|
|
||||||
|
|
||||||
using namespace KWayland::Client;
|
|
||||||
using namespace KWaylandServer;
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Qt::MouseButton)
|
|
||||||
|
|
||||||
class XdgShellTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
protected:
|
|
||||||
XdgShellTest(XdgShellInterfaceVersion version);
|
|
||||||
private Q_SLOTS:
|
|
||||||
void init();
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
void testCreateSurface();
|
|
||||||
void testTitle();
|
|
||||||
void testWindowClass();
|
|
||||||
void testMaximize();
|
|
||||||
void testMinimize();
|
|
||||||
void testFullscreen();
|
|
||||||
void testShowWindowMenu();
|
|
||||||
void testMove();
|
|
||||||
void testResize_data();
|
|
||||||
void testResize();
|
|
||||||
void testTransient();
|
|
||||||
void testPing();
|
|
||||||
void testClose();
|
|
||||||
void testConfigureStates_data();
|
|
||||||
void testConfigureStates();
|
|
||||||
void testConfigureMultipleAcks();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
XdgShellInterface *m_xdgShellInterface = nullptr;
|
|
||||||
Compositor *m_compositor = nullptr;
|
|
||||||
XdgShell *m_xdgShell = nullptr;
|
|
||||||
Display *m_display = nullptr;
|
|
||||||
CompositorInterface *m_compositorInterface = nullptr;
|
|
||||||
OutputInterface *m_o1Interface = nullptr;
|
|
||||||
OutputInterface *m_o2Interface = nullptr;
|
|
||||||
SeatInterface *m_seatInterface = nullptr;
|
|
||||||
ConnectionThread *m_connection = nullptr;
|
|
||||||
QThread *m_thread = nullptr;
|
|
||||||
EventQueue *m_queue = nullptr;
|
|
||||||
ShmPool *m_shmPool = nullptr;
|
|
||||||
Output *m_output1 = nullptr;
|
|
||||||
Output *m_output2 = nullptr;
|
|
||||||
Seat *m_seat = nullptr;
|
|
||||||
|
|
||||||
private:
|
|
||||||
XdgShellInterfaceVersion m_version;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SURFACE \
|
|
||||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated); \
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.isValid()); \
|
|
||||||
QScopedPointer<Surface> surface(m_compositor->createSurface()); \
|
|
||||||
QScopedPointer<XdgShellSurface> xdgSurface(m_xdgShell->createSurface(surface.data())); \
|
|
||||||
QCOMPARE(xdgSurface->size(), QSize()); \
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait()); \
|
|
||||||
auto serverXdgSurface = xdgSurfaceCreatedSpy.first().first().value<XdgShellSurfaceInterface*>(); \
|
|
||||||
QVERIFY(serverXdgSurface);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,245 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
|
||||||
SPDX-FileCopyrightText: 2017 David Edmundson <davidedmundson@kde.org>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "test_xdg_shell.h"
|
|
||||||
#include <wayland-xdg-shell-client-protocol.h>
|
|
||||||
|
|
||||||
class XdgShellTestStable : public XdgShellTest {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
XdgShellTestStable() :
|
|
||||||
XdgShellTest(KWaylandServer::XdgShellInterfaceVersion::Stable) {}
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void testMaxSize();
|
|
||||||
void testMinSize();
|
|
||||||
|
|
||||||
void testPopup_data();
|
|
||||||
void testPopup();
|
|
||||||
|
|
||||||
void testMultipleRoles1();
|
|
||||||
void testMultipleRoles2();
|
|
||||||
|
|
||||||
void testWindowGeometry();
|
|
||||||
};
|
|
||||||
|
|
||||||
void XdgShellTestStable::testMaxSize()
|
|
||||||
{
|
|
||||||
qRegisterMetaType<OutputInterface*>();
|
|
||||||
// this test verifies changing the window maxSize
|
|
||||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.isValid());
|
|
||||||
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
|
||||||
QScopedPointer<XdgShellSurface> xdgSurface(m_xdgShell->createSurface(surface.data()));
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
|
||||||
auto serverXdgSurface = xdgSurfaceCreatedSpy.first().first().value<XdgShellSurfaceInterface*>();
|
|
||||||
QVERIFY(serverXdgSurface);
|
|
||||||
|
|
||||||
QSignalSpy maxSizeSpy(serverXdgSurface, &XdgShellSurfaceInterface::maxSizeChanged);
|
|
||||||
QVERIFY(maxSizeSpy.isValid());
|
|
||||||
|
|
||||||
xdgSurface->setMaxSize(QSize(100, 100));
|
|
||||||
surface->commit(Surface::CommitFlag::None);
|
|
||||||
QVERIFY(maxSizeSpy.wait());
|
|
||||||
QCOMPARE(maxSizeSpy.count(), 1);
|
|
||||||
QCOMPARE(maxSizeSpy.last().at(0).value<QSize>(), QSize(100,100));
|
|
||||||
QCOMPARE(serverXdgSurface->maximumSize(), QSize(100, 100));
|
|
||||||
|
|
||||||
xdgSurface->setMaxSize(QSize(200, 200));
|
|
||||||
surface->commit(Surface::CommitFlag::None);
|
|
||||||
QVERIFY(maxSizeSpy.wait());
|
|
||||||
QCOMPARE(maxSizeSpy.count(), 2);
|
|
||||||
QCOMPARE(maxSizeSpy.last().at(0).value<QSize>(), QSize(200,200));
|
|
||||||
QCOMPARE(serverXdgSurface->maximumSize(), QSize(200, 200));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void XdgShellTestStable::testPopup_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<XdgPositioner>("positioner");
|
|
||||||
XdgPositioner positioner(QSize(10,10), QRect(100,100,50,50));
|
|
||||||
QTest::newRow("default") << positioner;
|
|
||||||
|
|
||||||
XdgPositioner positioner2(QSize(20,20), QRect(101,102,51,52));
|
|
||||||
QTest::newRow("sizeAndAnchorRect") << positioner2;
|
|
||||||
|
|
||||||
positioner.setAnchorEdge(Qt::TopEdge | Qt::RightEdge);
|
|
||||||
QTest::newRow("anchorEdge") << positioner;
|
|
||||||
|
|
||||||
positioner.setGravity(Qt::BottomEdge);
|
|
||||||
QTest::newRow("gravity") << positioner;
|
|
||||||
|
|
||||||
positioner.setGravity(Qt::TopEdge | Qt::RightEdge);
|
|
||||||
QTest::newRow("gravity2") << positioner;
|
|
||||||
|
|
||||||
positioner.setConstraints(XdgPositioner::Constraint::SlideX | XdgPositioner::Constraint::FlipY);
|
|
||||||
QTest::newRow("constraints") << positioner;
|
|
||||||
|
|
||||||
positioner.setConstraints(XdgPositioner::Constraint::SlideX | XdgPositioner::Constraint::SlideY | XdgPositioner::Constraint::FlipX | XdgPositioner::Constraint::FlipY | XdgPositioner::Constraint::ResizeX | XdgPositioner::Constraint::ResizeY);
|
|
||||||
QTest::newRow("constraints2") << positioner;
|
|
||||||
|
|
||||||
positioner.setAnchorOffset(QPoint(4,5));
|
|
||||||
QTest::newRow("offset") << positioner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void XdgShellTestStable::testPopup()
|
|
||||||
{
|
|
||||||
QSignalSpy xdgTopLevelCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
|
||||||
QSignalSpy xdgPopupCreatedSpy(m_xdgShellInterface, &XdgShellInterface::xdgPopupCreated);
|
|
||||||
|
|
||||||
QScopedPointer<Surface> parentSurface(m_compositor->createSurface());
|
|
||||||
QScopedPointer<XdgShellSurface> xdgParentSurface(m_xdgShell->createSurface(parentSurface.data()));
|
|
||||||
|
|
||||||
QVERIFY(xdgTopLevelCreatedSpy.wait());
|
|
||||||
auto serverXdgTopLevel = xdgTopLevelCreatedSpy.first().first().value<XdgShellSurfaceInterface*>();
|
|
||||||
|
|
||||||
QFETCH(XdgPositioner, positioner);
|
|
||||||
|
|
||||||
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
|
||||||
QScopedPointer<XdgShellPopup> xdgSurface(m_xdgShell->createPopup(surface.data(), xdgParentSurface.data(), positioner));
|
|
||||||
QVERIFY(xdgPopupCreatedSpy.wait());
|
|
||||||
auto serverXdgPopup = xdgPopupCreatedSpy.first().first().value<XdgShellPopupInterface*>();
|
|
||||||
QVERIFY(serverXdgPopup);
|
|
||||||
|
|
||||||
QCOMPARE(serverXdgPopup->initialSize(), positioner.initialSize());
|
|
||||||
QCOMPARE(serverXdgPopup->anchorRect(), positioner.anchorRect());
|
|
||||||
QCOMPARE(serverXdgPopup->anchorEdge(), positioner.anchorEdge());
|
|
||||||
QCOMPARE(serverXdgPopup->gravity(), positioner.gravity());
|
|
||||||
QCOMPARE(serverXdgPopup->anchorOffset(), positioner.anchorOffset());
|
|
||||||
//we have different enums for client server, but they share the same values
|
|
||||||
QCOMPARE((int)serverXdgPopup->constraintAdjustments(), (int)positioner.constraints());
|
|
||||||
QCOMPARE(serverXdgPopup->transientFor().data(), serverXdgTopLevel->surface());
|
|
||||||
}
|
|
||||||
|
|
||||||
void XdgShellTestStable::testMinSize()
|
|
||||||
{
|
|
||||||
qRegisterMetaType<OutputInterface*>();
|
|
||||||
// this test verifies changing the window minSize
|
|
||||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.isValid());
|
|
||||||
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
|
||||||
QScopedPointer<XdgShellSurface> xdgSurface(m_xdgShell->createSurface(surface.data()));
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
|
||||||
auto serverXdgSurface = xdgSurfaceCreatedSpy.first().first().value<XdgShellSurfaceInterface*>();
|
|
||||||
QVERIFY(serverXdgSurface);
|
|
||||||
|
|
||||||
QSignalSpy minSizeSpy(serverXdgSurface, &XdgShellSurfaceInterface::minSizeChanged);
|
|
||||||
QVERIFY(minSizeSpy.isValid());
|
|
||||||
|
|
||||||
xdgSurface->setMinSize(QSize(200, 200));
|
|
||||||
surface->commit(Surface::CommitFlag::None);
|
|
||||||
QVERIFY(minSizeSpy.wait());
|
|
||||||
QCOMPARE(minSizeSpy.count(), 1);
|
|
||||||
QCOMPARE(minSizeSpy.last().at(0).value<QSize>(), QSize(200,200));
|
|
||||||
QCOMPARE(serverXdgSurface->minimumSize(), QSize(200, 200));
|
|
||||||
|
|
||||||
xdgSurface->setMinSize(QSize(100, 100));
|
|
||||||
surface->commit(Surface::CommitFlag::None);
|
|
||||||
QVERIFY(minSizeSpy.wait());
|
|
||||||
QCOMPARE(minSizeSpy.count(), 2);
|
|
||||||
QCOMPARE(minSizeSpy.last().at(0).value<QSize>(), QSize(100,100));
|
|
||||||
QCOMPARE(serverXdgSurface->minimumSize(), QSize(100, 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
//top level then toplevel
|
|
||||||
void XdgShellTestStable::testMultipleRoles1()
|
|
||||||
{
|
|
||||||
//setting multiple roles on an xdg surface should fail
|
|
||||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
|
||||||
QSignalSpy xdgPopupCreatedSpy(m_xdgShellInterface, &XdgShellInterface::xdgPopupCreated);
|
|
||||||
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.isValid());
|
|
||||||
QVERIFY(xdgPopupCreatedSpy.isValid());
|
|
||||||
|
|
||||||
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
|
||||||
//This is testing we work when a client does something stupid
|
|
||||||
//we can't use KWayland API here because by design that stops you from doing anything stupid
|
|
||||||
|
|
||||||
qDebug() << (xdg_wm_base*)*m_xdgShell;
|
|
||||||
auto xdgSurface = xdg_wm_base_get_xdg_surface(*m_xdgShell, *surface.data());
|
|
||||||
|
|
||||||
//create a top level
|
|
||||||
auto xdgTopLevel1 = xdg_surface_get_toplevel(xdgSurface);
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
|
||||||
|
|
||||||
//now try to create another top level for the same xdg surface. It should fail
|
|
||||||
auto xdgTopLevel2 = xdg_surface_get_toplevel(xdgSurface);
|
|
||||||
QVERIFY(!xdgSurfaceCreatedSpy.wait(10));
|
|
||||||
|
|
||||||
xdg_toplevel_destroy(xdgTopLevel1);
|
|
||||||
xdg_toplevel_destroy(xdgTopLevel2);
|
|
||||||
xdg_surface_destroy(xdgSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
//toplevel then popup
|
|
||||||
void XdgShellTestStable::testMultipleRoles2()
|
|
||||||
{
|
|
||||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
|
||||||
QSignalSpy xdgPopupCreatedSpy(m_xdgShellInterface, &XdgShellInterface::xdgPopupCreated);
|
|
||||||
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.isValid());
|
|
||||||
QVERIFY(xdgPopupCreatedSpy.isValid());
|
|
||||||
|
|
||||||
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
|
||||||
QScopedPointer<Surface> parentSurface(m_compositor->createSurface());
|
|
||||||
|
|
||||||
auto parentXdgSurface = xdg_wm_base_get_xdg_surface(*m_xdgShell, *parentSurface.data());
|
|
||||||
auto xdgTopLevelParent = xdg_surface_get_toplevel(parentXdgSurface);
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
|
||||||
|
|
||||||
|
|
||||||
auto xdgSurface = xdg_wm_base_get_xdg_surface(*m_xdgShell, *surface.data());
|
|
||||||
//create a top level
|
|
||||||
auto xdgTopLevel1 = xdg_surface_get_toplevel(xdgSurface);
|
|
||||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
|
||||||
|
|
||||||
//now try to create a popup on the same xdg surface. It should fail
|
|
||||||
|
|
||||||
auto positioner = xdg_wm_base_create_positioner(*m_xdgShell);
|
|
||||||
xdg_positioner_set_anchor_rect(positioner,10, 10, 10, 10);
|
|
||||||
xdg_positioner_set_size(positioner,10, 100);
|
|
||||||
|
|
||||||
auto xdgPopup2 = xdg_surface_get_popup(xdgSurface, parentXdgSurface, positioner);
|
|
||||||
QVERIFY(!xdgPopupCreatedSpy.wait(10));
|
|
||||||
|
|
||||||
xdg_positioner_destroy(positioner);
|
|
||||||
xdg_toplevel_destroy(xdgTopLevel1);
|
|
||||||
xdg_toplevel_destroy(xdgTopLevelParent);
|
|
||||||
xdg_popup_destroy(xdgPopup2);
|
|
||||||
xdg_surface_destroy(xdgSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XdgShellTestStable::testWindowGeometry()
|
|
||||||
{
|
|
||||||
SURFACE
|
|
||||||
QSignalSpy windowGeometryChangedSpy(serverXdgSurface, &XdgShellSurfaceInterface::windowGeometryChanged);
|
|
||||||
xdgSurface->setWindowGeometry(QRect(50, 50, 400, 400));
|
|
||||||
surface->commit(Surface::CommitFlag::None);
|
|
||||||
QVERIFY(windowGeometryChangedSpy.wait());
|
|
||||||
QCOMPARE(serverXdgSurface->windowGeometry(), QRect(50, 50, 400, 400));
|
|
||||||
|
|
||||||
//add a popup to this surface
|
|
||||||
XdgPositioner positioner(QSize(10,10), QRect(100,100,50,50));
|
|
||||||
QSignalSpy xdgPopupCreatedSpy(m_xdgShellInterface, &XdgShellInterface::xdgPopupCreated);
|
|
||||||
QScopedPointer<Surface> popupSurface(m_compositor->createSurface());
|
|
||||||
QScopedPointer<XdgShellPopup> xdgPopupSurface(m_xdgShell->createPopup(popupSurface.data(), xdgSurface.data(), positioner));
|
|
||||||
QVERIFY(xdgPopupCreatedSpy.wait());
|
|
||||||
auto serverXdgPopup = xdgPopupCreatedSpy.first().first().value<XdgShellPopupInterface*>();
|
|
||||||
QVERIFY(serverXdgPopup);
|
|
||||||
|
|
||||||
QSignalSpy popupWindowGeometryChangedSpy(serverXdgPopup, &XdgShellPopupInterface::windowGeometryChanged);
|
|
||||||
xdgPopupSurface->setWindowGeometry(QRect(60, 60, 300, 300));
|
|
||||||
popupSurface->commit(Surface::CommitFlag::None);
|
|
||||||
QVERIFY(popupWindowGeometryChangedSpy.wait());
|
|
||||||
QCOMPARE(serverXdgPopup->windowGeometry(), QRect(60, 60, 300, 300));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(XdgShellTestStable)
|
|
||||||
|
|
||||||
#include "test_xdg_shell_stable.moc"
|
|
||||||
|
|
|
@ -39,10 +39,10 @@
|
||||||
#include "subcompositor_interface.h"
|
#include "subcompositor_interface.h"
|
||||||
#include "tablet_interface.h"
|
#include "tablet_interface.h"
|
||||||
#include "textinput_interface_p.h"
|
#include "textinput_interface_p.h"
|
||||||
#include "xdgdecoration_interface.h"
|
#include "xdgdecoration_v1_interface.h"
|
||||||
#include "xdgforeign_interface.h"
|
#include "xdgforeign_interface.h"
|
||||||
#include "xdgoutput_interface.h"
|
#include "xdgoutput_interface.h"
|
||||||
#include "xdgshell_stable_interface_p.h"
|
#include "xdgshell_interface.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -377,20 +377,11 @@ TextInputManagerInterface *Display::createTextInputManager(const TextInputInterf
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
XdgShellInterface *Display::createXdgShell(const XdgShellInterfaceVersion &version, QObject *parent)
|
XdgShellInterface *Display::createXdgShell(QObject *parent)
|
||||||
{
|
{
|
||||||
XdgShellInterface *x = nullptr;
|
XdgShellInterface *shell = new XdgShellInterface(this, parent);
|
||||||
switch (version) {
|
connect(this, &Display::aboutToTerminate, shell, [shell] { delete shell; });
|
||||||
case XdgShellInterfaceVersion::UnstableV5:
|
return shell;
|
||||||
return nullptr;
|
|
||||||
case XdgShellInterfaceVersion::UnstableV6:
|
|
||||||
return nullptr;
|
|
||||||
case XdgShellInterfaceVersion::Stable:
|
|
||||||
x = new XdgShellStableInterface(this, parent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
connect(this, &Display::aboutToTerminate, x, [x] { delete x; });
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RelativePointerManagerInterface *Display::createRelativePointerManager(const RelativePointerInterfaceVersion &version, QObject *parent)
|
RelativePointerManagerInterface *Display::createRelativePointerManager(const RelativePointerInterfaceVersion &version, QObject *parent)
|
||||||
|
@ -483,9 +474,9 @@ XdgOutputManagerInterface *Display::createXdgOutputManager(QObject *parent)
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
XdgDecorationManagerInterface *Display::createXdgDecorationManager(XdgShellInterface *shellInterface, QObject *parent)
|
XdgDecorationManagerV1Interface *Display::createXdgDecorationManagerV1(QObject *parent)
|
||||||
{
|
{
|
||||||
auto d = new XdgDecorationManagerInterface(this, shellInterface, parent);
|
auto d = new XdgDecorationManagerV1Interface(this, parent);
|
||||||
connect(this, &Display::aboutToTerminate, d, [d] { delete d; });
|
connect(this, &Display::aboutToTerminate, d, [d] { delete d; });
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ class AppMenuManagerInterface;
|
||||||
class ServerSideDecorationPaletteManagerInterface;
|
class ServerSideDecorationPaletteManagerInterface;
|
||||||
class PlasmaVirtualDesktopManagementInterface;
|
class PlasmaVirtualDesktopManagementInterface;
|
||||||
class XdgOutputManagerInterface;
|
class XdgOutputManagerInterface;
|
||||||
class XdgDecorationManagerInterface;
|
class XdgDecorationManagerV1Interface;
|
||||||
class EglStreamControllerInterface;
|
class EglStreamControllerInterface;
|
||||||
class KeyStateInterface;
|
class KeyStateInterface;
|
||||||
class LinuxDmabufUnstableV1Interface;
|
class LinuxDmabufUnstableV1Interface;
|
||||||
|
@ -210,7 +210,7 @@ public:
|
||||||
*
|
*
|
||||||
* @since 5.25
|
* @since 5.25
|
||||||
**/
|
**/
|
||||||
XdgShellInterface *createXdgShell(const XdgShellInterfaceVersion &version, QObject *parent = nullptr);
|
XdgShellInterface *createXdgShell(QObject *parent = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the RelativePointerManagerInterface in interface @p version
|
* Creates the RelativePointerManagerInterface in interface @p version
|
||||||
|
@ -299,7 +299,7 @@ public:
|
||||||
* @return the created manager
|
* @return the created manager
|
||||||
* @since 5.54
|
* @since 5.54
|
||||||
*/
|
*/
|
||||||
XdgDecorationManagerInterface *createXdgDecorationManager(XdgShellInterface *shellInterface, QObject *parent = nullptr);
|
XdgDecorationManagerV1Interface *createXdgDecorationManagerV1(QObject *parent = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the EglStreamControllerInterface
|
* Creates the EglStreamControllerInterface
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
||||||
*/
|
|
||||||
#ifndef KWAYLAND_SERVER_GENERIC_SHELL_SURFACE_P_H
|
|
||||||
#define KWAYLAND_SERVER_GENERIC_SHELL_SURFACE_P_H
|
|
||||||
|
|
||||||
#include "seat_interface.h"
|
|
||||||
#include "surface_interface.h"
|
|
||||||
#include "surfacerole_p.h"
|
|
||||||
#include <wayland-server.h>
|
|
||||||
|
|
||||||
namespace KWaylandServer
|
|
||||||
{
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class GenericShellSurface : public SurfaceRole
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GenericShellSurface(T *shellSurface, SurfaceInterface *surface)
|
|
||||||
: SurfaceRole(surface)
|
|
||||||
, surface(surface)
|
|
||||||
, shellSurface(shellSurface)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SurfaceInterface *surface;
|
|
||||||
QString title;
|
|
||||||
QByteArray windowClass;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void setTitle(const QString &title);
|
|
||||||
void setWindowClass(const QByteArray &wc);
|
|
||||||
|
|
||||||
static void moveCallback(wl_client *client, wl_resource *resource, wl_resource *seat, uint32_t serial);
|
|
||||||
template <typename U>
|
|
||||||
static void resizeCallback(wl_client *client, wl_resource *resource, wl_resource * seat, uint32_t serial, uint32_t edges);
|
|
||||||
static void setTitleCallback(wl_client *client, wl_resource *resource, const char *title);
|
|
||||||
static void setAppIdCallback(wl_client *client, wl_resource *resource, const char *app_id);
|
|
||||||
|
|
||||||
private:
|
|
||||||
T *q_func() {
|
|
||||||
return shellSurface;
|
|
||||||
}
|
|
||||||
static typename T::Private *userData(wl_resource *resource) {
|
|
||||||
return reinterpret_cast<typename T::Private*>(wl_resource_get_user_data(resource));
|
|
||||||
}
|
|
||||||
T *shellSurface;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void GenericShellSurface<T>::setTitleCallback(wl_client *client, wl_resource *resource, const char *title)
|
|
||||||
{
|
|
||||||
auto s = userData(resource);
|
|
||||||
Q_ASSERT(client == *s->client);
|
|
||||||
s->setTitle(QString::fromUtf8(title));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void GenericShellSurface<T>::setAppIdCallback(wl_client *client, wl_resource *resource, const char *app_id)
|
|
||||||
{
|
|
||||||
auto s = userData(resource);
|
|
||||||
Q_ASSERT(client == *s->client);
|
|
||||||
s->setWindowClass(QByteArray(app_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void GenericShellSurface<T>::setTitle(const QString &t)
|
|
||||||
{
|
|
||||||
if (title == t) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
title = t;
|
|
||||||
Q_Q(T);
|
|
||||||
emit q->titleChanged(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void GenericShellSurface<T>::setWindowClass(const QByteArray &wc)
|
|
||||||
{
|
|
||||||
if (windowClass == wc) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
windowClass = wc;
|
|
||||||
Q_Q(T);
|
|
||||||
emit q->windowClassChanged(windowClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void GenericShellSurface<T>::moveCallback(wl_client *client, wl_resource *resource, wl_resource *seat, uint32_t serial)
|
|
||||||
{
|
|
||||||
auto s = userData(resource);
|
|
||||||
Q_ASSERT(client == *s->client);
|
|
||||||
emit s->q_func()->moveRequested(SeatInterface::get(seat), serial);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
template <typename T>
|
|
||||||
Qt::Edges edgesToQtEdges(T edges);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
template <typename U>
|
|
||||||
void GenericShellSurface<T>::resizeCallback(wl_client *client, wl_resource *resource, wl_resource * seat, uint32_t serial, uint32_t edges)
|
|
||||||
{
|
|
||||||
auto s = userData(resource);
|
|
||||||
Q_ASSERT(client == *s->client);
|
|
||||||
emit s->q_func()->resizeRequested(SeatInterface::get(seat), serial, edgesToQtEdges(U(edges)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,233 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2018 David Edmundson <kde@davidedmundson.co.uk>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
||||||
*/
|
|
||||||
#include "xdgdecoration_interface.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "display.h"
|
|
||||||
#include "global_p.h"
|
|
||||||
#include "resource_p.h"
|
|
||||||
#include "xdgshell_interface.h"
|
|
||||||
#include "xdgshell_stable_interface_p.h"
|
|
||||||
|
|
||||||
#include "wayland-xdg-decoration-server-protocol.h"
|
|
||||||
|
|
||||||
#include <QtDebug>
|
|
||||||
#include <QPointer>
|
|
||||||
|
|
||||||
namespace KWaylandServer
|
|
||||||
{
|
|
||||||
|
|
||||||
class XdgDecorationManagerInterface::Private : public Global::Private
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Private(XdgDecorationManagerInterface *q, XdgShellInterface *shellInterface, Display *d);
|
|
||||||
|
|
||||||
QHash<XdgShellSurfaceInterface*, XdgDecorationInterface*> m_decorations;
|
|
||||||
KWaylandServer::XdgShellStableInterface *m_shellInterface;
|
|
||||||
private:
|
|
||||||
void bind(wl_client *client, uint32_t version, uint32_t id) override;
|
|
||||||
|
|
||||||
static void unbind(wl_resource *resource);
|
|
||||||
static Private *cast(wl_resource *r) {
|
|
||||||
return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyCallback(wl_client *client, wl_resource *resource);
|
|
||||||
static void getToplevelDecorationCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * toplevel);
|
|
||||||
|
|
||||||
XdgDecorationManagerInterface *q;
|
|
||||||
static const struct zxdg_decoration_manager_v1_interface s_interface;
|
|
||||||
static const quint32 s_version;
|
|
||||||
};
|
|
||||||
|
|
||||||
const quint32 XdgDecorationManagerInterface::Private::s_version = 1;
|
|
||||||
|
|
||||||
XdgDecorationManagerInterface::XdgDecorationManagerInterface(Display *display, XdgShellInterface *shellInterface, QObject *parent):
|
|
||||||
Global(new Private(this, shellInterface, display), parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgDecorationManagerInterface::~XdgDecorationManagerInterface() {}
|
|
||||||
|
|
||||||
#ifndef K_DOXYGEN
|
|
||||||
const struct zxdg_decoration_manager_v1_interface XdgDecorationManagerInterface::Private::s_interface = {
|
|
||||||
destroyCallback,
|
|
||||||
getToplevelDecorationCallback
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void XdgDecorationManagerInterface::Private::destroyCallback(wl_client *client, wl_resource *resource)
|
|
||||||
{
|
|
||||||
Q_UNUSED(client)
|
|
||||||
wl_resource_destroy(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XdgDecorationManagerInterface::Private::getToplevelDecorationCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * toplevel)
|
|
||||||
{
|
|
||||||
auto p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
|
|
||||||
Q_ASSERT(p);
|
|
||||||
|
|
||||||
auto shell = p->m_shellInterface->getSurface(toplevel);
|
|
||||||
if (!shell) {
|
|
||||||
wl_resource_post_error(resource, ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED, "No XDGToplevel found object");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (p->m_decorations.contains(shell)) {
|
|
||||||
wl_resource_post_error(resource, ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED, "XDGDecoration already exists for this surface");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto xdgDecoration = new XdgDecorationInterface(p->q, shell, resource);
|
|
||||||
xdgDecoration->create(p->display->getConnection(client), wl_resource_get_version(resource), id);
|
|
||||||
if (!xdgDecoration->resource()) {
|
|
||||||
wl_resource_post_no_memory(resource);
|
|
||||||
delete xdgDecoration;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p->m_decorations[shell] = xdgDecoration;
|
|
||||||
QObject::connect(xdgDecoration, &QObject::destroyed, p->q, [=]() {
|
|
||||||
p->m_decorations.remove(shell);
|
|
||||||
});
|
|
||||||
emit p->q->xdgDecorationInterfaceCreated(xdgDecoration);
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgDecorationManagerInterface::Private::Private(XdgDecorationManagerInterface *q, XdgShellInterface *shellInterface, Display *d)
|
|
||||||
: Global::Private(d, &zxdg_decoration_manager_v1_interface, s_version)
|
|
||||||
, q(q)
|
|
||||||
{
|
|
||||||
m_shellInterface = qobject_cast<XdgShellStableInterface*>(shellInterface);
|
|
||||||
Q_ASSERT(m_shellInterface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XdgDecorationManagerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
|
|
||||||
{
|
|
||||||
auto c = display->getConnection(client);
|
|
||||||
wl_resource *resource = c->createResource(&zxdg_decoration_manager_v1_interface, qMin(version, s_version), id);
|
|
||||||
if (!resource) {
|
|
||||||
wl_client_post_no_memory(client);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wl_resource_set_implementation(resource, &s_interface, this, unbind);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XdgDecorationManagerInterface::Private::unbind(wl_resource *resource)
|
|
||||||
{
|
|
||||||
Q_UNUSED(resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
class XdgDecorationInterface::Private : public Resource::Private
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Private(XdgDecorationInterface *q, XdgDecorationManagerInterface *c, XdgShellSurfaceInterface *s, wl_resource *parentResource);
|
|
||||||
~Private();
|
|
||||||
Mode m_requestedMode = Mode::Undefined;
|
|
||||||
XdgShellSurfaceInterface* m_shell;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void setModeCallback(wl_client *client, wl_resource *resource, uint32_t mode);
|
|
||||||
static void unsetModeCallback(wl_client *client, wl_resource *resource);
|
|
||||||
|
|
||||||
XdgDecorationInterface *q_func() {
|
|
||||||
return reinterpret_cast<XdgDecorationInterface *>(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct zxdg_toplevel_decoration_v1_interface s_interface;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef K_DOXYGEN
|
|
||||||
const struct zxdg_toplevel_decoration_v1_interface XdgDecorationInterface::Private::s_interface = {
|
|
||||||
resourceDestroyedCallback,
|
|
||||||
setModeCallback,
|
|
||||||
unsetModeCallback
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void XdgDecorationInterface::Private::setModeCallback(wl_client *client, wl_resource *resource, uint32_t mode_raw)
|
|
||||||
{
|
|
||||||
Q_UNUSED(client);
|
|
||||||
auto p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
|
|
||||||
Q_ASSERT(p);
|
|
||||||
|
|
||||||
Mode mode = Mode::Undefined;
|
|
||||||
switch (mode_raw) {
|
|
||||||
case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE:
|
|
||||||
mode = Mode::ClientSide;
|
|
||||||
break;
|
|
||||||
case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE:
|
|
||||||
mode = Mode::ServerSide;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->m_requestedMode = mode;
|
|
||||||
emit p->q_func()->modeRequested(p->m_requestedMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XdgDecorationInterface::Private::unsetModeCallback(wl_client *client, wl_resource *resource)
|
|
||||||
{
|
|
||||||
Q_UNUSED(client);
|
|
||||||
auto p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
|
|
||||||
Q_ASSERT(p);
|
|
||||||
|
|
||||||
p->m_requestedMode = Mode::Undefined;
|
|
||||||
emit p->q_func()->modeRequested(p->m_requestedMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgDecorationInterface::Private::Private(XdgDecorationInterface *q, XdgDecorationManagerInterface *c, XdgShellSurfaceInterface *shell, wl_resource *parentResource)
|
|
||||||
: Resource::Private(q, c, parentResource, &zxdg_toplevel_decoration_v1_interface, &s_interface)
|
|
||||||
, m_shell(shell)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgDecorationInterface::Private::~Private()
|
|
||||||
{
|
|
||||||
if (resource) {
|
|
||||||
wl_resource_destroy(resource);
|
|
||||||
resource = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgDecorationInterface::XdgDecorationInterface(XdgDecorationManagerInterface *parent, XdgShellSurfaceInterface *shell, wl_resource *parentResource)
|
|
||||||
: Resource(new Private(this, parent, shell, parentResource))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgDecorationInterface::~XdgDecorationInterface() {}
|
|
||||||
|
|
||||||
void XdgDecorationInterface::configure(XdgDecorationInterface::Mode mode)
|
|
||||||
{
|
|
||||||
switch(mode) {
|
|
||||||
case Mode::ClientSide:
|
|
||||||
zxdg_toplevel_decoration_v1_send_configure(resource(), ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
|
|
||||||
break;
|
|
||||||
case Mode::ServerSide:
|
|
||||||
zxdg_toplevel_decoration_v1_send_configure(resource(), ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//configure(Mode::Undefined) should no-op, as it semantically makes no sense
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgDecorationInterface::Mode XdgDecorationInterface::requestedMode() const
|
|
||||||
{
|
|
||||||
Q_D();
|
|
||||||
return d->m_requestedMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgShellSurfaceInterface* XdgDecorationInterface::surface() const
|
|
||||||
{
|
|
||||||
Q_D();
|
|
||||||
return d->m_shell;
|
|
||||||
}
|
|
||||||
|
|
||||||
XdgDecorationInterface::Private *XdgDecorationInterface::d_func() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<XdgDecorationInterface::Private*>(d.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2018 David Edmundson <kde@davidedmundson.co.uk>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
||||||
*/
|
|
||||||
#ifndef KWAYLAND_SERVER_XDG_DECORATION_UNSTABLE_V1_H
|
|
||||||
#define KWAYLAND_SERVER_XDG_DECORATION_UNSTABLE_V1_H
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#include <KWaylandServer/kwaylandserver_export.h>
|
|
||||||
|
|
||||||
namespace KWaylandServer
|
|
||||||
{
|
|
||||||
|
|
||||||
class Display;
|
|
||||||
class XdgDecorationInterface;
|
|
||||||
class XdgShellInterface;
|
|
||||||
class XdgShellSurfaceInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The XdgDecorationManagerInterface class
|
|
||||||
* @since 5.54
|
|
||||||
*/
|
|
||||||
class KWAYLANDSERVER_EXPORT XdgDecorationManagerInterface : public Global
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
~XdgDecorationManagerInterface() override;
|
|
||||||
Q_SIGNALS:
|
|
||||||
void xdgDecorationInterfaceCreated(XdgDecorationInterface *iface);
|
|
||||||
private:
|
|
||||||
explicit XdgDecorationManagerInterface(Display *display, XdgShellInterface *shellInterface, QObject *parent = nullptr);
|
|
||||||
friend class Display;
|
|
||||||
class Private;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The XdgDecorationInterface class
|
|
||||||
* @since 5.54
|
|
||||||
*/
|
|
||||||
class KWAYLANDSERVER_EXPORT XdgDecorationInterface : public Resource
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum class Mode {
|
|
||||||
Undefined,
|
|
||||||
ClientSide,
|
|
||||||
ServerSide
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_ENUM(Mode);
|
|
||||||
|
|
||||||
~XdgDecorationInterface() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the mode the client should be using.
|
|
||||||
* It should be followed by a call to XDGShellSurface::configure()
|
|
||||||
* Once acked, it can relied upon to be applied in the next surface
|
|
||||||
*/
|
|
||||||
void configure(Mode requestedMode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The last mode requested by the client
|
|
||||||
*/
|
|
||||||
Mode requestedMode() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The surface this decoration is attached to
|
|
||||||
*/
|
|
||||||
XdgShellSurfaceInterface *surface() const;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
/**
|
|
||||||
* New mode requested by the client
|
|
||||||
*/
|
|
||||||
void modeRequested(KWaylandServer::XdgDecorationInterface::Mode requestedMode);
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit XdgDecorationInterface(XdgDecorationManagerInterface *parent, XdgShellSurfaceInterface *surface, wl_resource *parentResource);
|
|
||||||
friend class XdgDecorationManagerInterface;
|
|
||||||
|
|
||||||
class Private;
|
|
||||||
Private *d_func() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,131 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2017 David Edmundson <davidedmundson@kde.org>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
||||||
*/
|
|
||||||
#ifndef KWAYLAND_SERVER_XDGSHELL_STABLE_INTERFACE_P_H
|
|
||||||
#define KWAYLAND_SERVER_XDGSHELL_STABLE_INTERFACE_P_H
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
#include "resource.h"
|
|
||||||
#include "xdgshell_interface.h"
|
|
||||||
|
|
||||||
#include <KWaylandServer/kwaylandserver_export.h>
|
|
||||||
|
|
||||||
#include <QSize>
|
|
||||||
|
|
||||||
namespace KWaylandServer
|
|
||||||
{
|
|
||||||
|
|
||||||
class Display;
|
|
||||||
class OutputInterface;
|
|
||||||
class SeatInterface;
|
|
||||||
class SurfaceInterface;
|
|
||||||
class XdgTopLevelStableInterface;
|
|
||||||
class XdgPopupStableInterface;
|
|
||||||
class XdgPositionerStableInterface;
|
|
||||||
class XdgSurfaceStableInterface;
|
|
||||||
template <typename T>
|
|
||||||
class GenericShellSurface;
|
|
||||||
|
|
||||||
class XdgShellStableInterface : public XdgShellInterface
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
virtual ~XdgShellStableInterface();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns The XdgTopLevelV6Interface for the @p native resource.
|
|
||||||
**/
|
|
||||||
XdgTopLevelStableInterface *getSurface(wl_resource *native);
|
|
||||||
//DAVE we want to rename this, as it's bloody confusing. But XdgShellInterface::getSurface exists and expects that
|
|
||||||
//also use a less terrible argument name than native. It's obvious it's native from the type
|
|
||||||
|
|
||||||
XdgPositionerStableInterface *getPositioner(wl_resource *native);
|
|
||||||
|
|
||||||
XdgSurfaceStableInterface *realGetSurface(wl_resource *native);
|
|
||||||
|
|
||||||
Display *display() const;
|
|
||||||
|
|
||||||
void ping(XdgShellSurfaceInterface * surface);
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit XdgShellStableInterface(Display *display, QObject *parent = nullptr);
|
|
||||||
friend class Display;
|
|
||||||
class Private;
|
|
||||||
Private *d_func() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class XdgSurfaceStableInterface : public KWaylandServer::Resource
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
virtual ~XdgSurfaceStableInterface();
|
|
||||||
SurfaceInterface* surface() const;
|
|
||||||
XdgTopLevelStableInterface* topLevel() const;
|
|
||||||
XdgPopupStableInterface *popup() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit XdgSurfaceStableInterface(XdgShellStableInterface *parent, SurfaceInterface *surface, wl_resource *parentResource);
|
|
||||||
friend class XdgShellStableInterface;
|
|
||||||
|
|
||||||
class Private;
|
|
||||||
Private *d_func() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class XdgTopLevelStableInterface : public
|
|
||||||
XdgShellSurfaceInterface
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
virtual ~XdgTopLevelStableInterface();
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit XdgTopLevelStableInterface(XdgShellStableInterface *parent, SurfaceInterface *surface, wl_resource *parentResource);
|
|
||||||
friend class XdgShellStableInterface;
|
|
||||||
friend class XdgSurfaceStableInterface;
|
|
||||||
|
|
||||||
class Private;
|
|
||||||
Private *d_func() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class XdgPopupStableInterface : public XdgShellPopupInterface
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
virtual ~XdgPopupStableInterface();
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit XdgPopupStableInterface(XdgShellStableInterface *parent, SurfaceInterface *surface, wl_resource *parentResource);
|
|
||||||
friend class XdgShellStableInterface;
|
|
||||||
friend class XdgSurfaceStableInterface;
|
|
||||||
friend class GenericShellSurface<XdgPopupStableInterface>;
|
|
||||||
|
|
||||||
class Private;
|
|
||||||
Private *d_func() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a private internal class that keeps track of sent data
|
|
||||||
* At the time of PopupCreation these values are copied to the popup
|
|
||||||
*/
|
|
||||||
class XdgPositionerStableInterface: public KWaylandServer::Resource
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QSize initialSize() const;
|
|
||||||
QRect anchorRect() const;
|
|
||||||
Qt::Edges anchorEdge() const;
|
|
||||||
Qt::Edges gravity() const;
|
|
||||||
PositionerConstraints constraintAdjustments() const;
|
|
||||||
QPoint anchorOffset() const;
|
|
||||||
private:
|
|
||||||
explicit XdgPositionerStableInterface(XdgShellStableInterface *parent, wl_resource *parentResource);
|
|
||||||
friend class XdgShellStableInterface;
|
|
||||||
|
|
||||||
class Private;
|
|
||||||
Private *d_func() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -25,4 +25,13 @@ SurfaceRole::~SurfaceRole()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SurfaceRole *SurfaceRole::get(SurfaceInterface *surface)
|
||||||
|
{
|
||||||
|
if (surface) {
|
||||||
|
return surface->d_func()->role;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ public:
|
||||||
|
|
||||||
virtual void commit() = 0;
|
virtual void commit() = 0;
|
||||||
|
|
||||||
|
static SurfaceRole *get(SurfaceInterface *surface);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPointer<SurfaceInterface> m_surface;
|
QPointer<SurfaceInterface> m_surface;
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ public:
|
||||||
explicit CompositorWindow(QWidget *parent = nullptr);
|
explicit CompositorWindow(QWidget *parent = nullptr);
|
||||||
virtual ~CompositorWindow();
|
virtual ~CompositorWindow();
|
||||||
|
|
||||||
void surfaceCreated(KWaylandServer::XdgShellSurfaceInterface *surface);
|
void surfaceCreated(KWaylandServer::XdgToplevelInterface *surface);
|
||||||
|
|
||||||
void setSeat(const QPointer<KWaylandServer::SeatInterface> &seat);
|
void setSeat(const QPointer<KWaylandServer::SeatInterface> &seat);
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateFocus();
|
void updateFocus();
|
||||||
QList<KWaylandServer::XdgShellSurfaceInterface *> m_stackingOrder;
|
QList<KWaylandServer::XdgToplevelInterface *> m_stackingOrder;
|
||||||
QPointer<KWaylandServer::SeatInterface> m_seat;
|
QPointer<KWaylandServer::SeatInterface> m_seat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,13 +106,13 @@ CompositorWindow::CompositorWindow(QWidget *parent)
|
||||||
|
|
||||||
CompositorWindow::~CompositorWindow() = default;
|
CompositorWindow::~CompositorWindow() = default;
|
||||||
|
|
||||||
void CompositorWindow::surfaceCreated(KWaylandServer::XdgShellSurfaceInterface *surface)
|
void CompositorWindow::surfaceCreated(KWaylandServer::XdgToplevelInterface *surface)
|
||||||
{
|
{
|
||||||
using namespace KWaylandServer;
|
using namespace KWaylandServer;
|
||||||
surface->configure(XdgShellSurfaceInterface::States());
|
surface->sendConfigure(QSize(), XdgToplevelInterface::States());
|
||||||
m_stackingOrder << surface;
|
m_stackingOrder << surface;
|
||||||
connect(surface->surface(), &SurfaceInterface::damaged, this, static_cast<void (CompositorWindow::*)()>(&CompositorWindow::update));
|
connect(surface->surface(), &SurfaceInterface::damaged, this, static_cast<void (CompositorWindow::*)()>(&CompositorWindow::update));
|
||||||
connect(surface, &XdgShellSurfaceInterface::destroyed, this,
|
connect(surface, &XdgToplevelInterface::destroyed, this,
|
||||||
[surface, this] {
|
[surface, this] {
|
||||||
m_stackingOrder.removeAll(surface);
|
m_stackingOrder.removeAll(surface);
|
||||||
updateFocus();
|
updateFocus();
|
||||||
|
@ -129,7 +129,7 @@ void CompositorWindow::updateFocus()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto it = std::find_if(m_stackingOrder.constBegin(), m_stackingOrder.constEnd(),
|
auto it = std::find_if(m_stackingOrder.constBegin(), m_stackingOrder.constEnd(),
|
||||||
[](XdgShellSurfaceInterface *toplevel) {
|
[](XdgToplevelInterface *toplevel) {
|
||||||
return toplevel->surface()->isMapped();
|
return toplevel->surface()->isMapped();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -243,8 +243,7 @@ int main(int argc, char **argv)
|
||||||
ddm->create();
|
ddm->create();
|
||||||
CompositorInterface *compositor = display.createCompositor(&display);
|
CompositorInterface *compositor = display.createCompositor(&display);
|
||||||
compositor->create();
|
compositor->create();
|
||||||
XdgShellInterface *shell = display.createXdgShell(XdgShellInterfaceVersion::Stable);
|
XdgShellInterface *shell = display.createXdgShell();
|
||||||
shell->create();
|
|
||||||
display.createShm();
|
display.createShm();
|
||||||
OutputInterface *output = display.createOutput(&display);
|
OutputInterface *output = display.createOutput(&display);
|
||||||
output->setPhysicalSize(QSize(269, 202));
|
output->setPhysicalSize(QSize(269, 202));
|
||||||
|
@ -263,7 +262,7 @@ int main(int argc, char **argv)
|
||||||
compositorWindow.setMaximumSize(windowSize);
|
compositorWindow.setMaximumSize(windowSize);
|
||||||
compositorWindow.setGeometry(QRect(QPoint(0, 0), windowSize));
|
compositorWindow.setGeometry(QRect(QPoint(0, 0), windowSize));
|
||||||
compositorWindow.show();
|
compositorWindow.show();
|
||||||
QObject::connect(shell, &XdgShellInterface::surfaceCreated, &compositorWindow, &CompositorWindow::surfaceCreated);
|
QObject::connect(shell, &XdgShellInterface::toplevelCreated, &compositorWindow, &CompositorWindow::surfaceCreated);
|
||||||
|
|
||||||
// start XWayland
|
// start XWayland
|
||||||
if (parser.isSet(xwaylandOption)) {
|
if (parser.isSet(xwaylandOption)) {
|
||||||
|
|
|
@ -77,8 +77,8 @@ int main(int argc, char **argv)
|
||||||
display.createShm();
|
display.createShm();
|
||||||
CompositorInterface *compositor = display.createCompositor(&display);
|
CompositorInterface *compositor = display.createCompositor(&display);
|
||||||
compositor->create();
|
compositor->create();
|
||||||
XdgShellInterface *shell = display.createXdgShell(XdgShellInterfaceVersion::Stable);
|
XdgShellInterface *shell = display.createXdgShell();
|
||||||
shell->create();
|
Q_UNUSED(shell)
|
||||||
OutputInterface *output = display.createOutput(&display);
|
OutputInterface *output = display.createOutput(&display);
|
||||||
output->setPhysicalSize(QSize(10, 10));
|
output->setPhysicalSize(QSize(10, 10));
|
||||||
output->addMode(QSize(1024, 768));
|
output->addMode(QSize(1024, 768));
|
||||||
|
|
151
src/wayland/xdgdecoration_v1_interface.cpp
Normal file
151
src/wayland/xdgdecoration_v1_interface.cpp
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xdgdecoration_v1_interface.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "xdgdecoration_v1_interface_p.h"
|
||||||
|
#include "xdgshell_interface_p.h"
|
||||||
|
|
||||||
|
namespace KWaylandServer
|
||||||
|
{
|
||||||
|
|
||||||
|
// TODO: We need to wait for an ack_configure either here or in xdgshellclient.cpp.
|
||||||
|
|
||||||
|
XdgDecorationManagerV1InterfacePrivate::XdgDecorationManagerV1InterfacePrivate(XdgDecorationManagerV1Interface *manager)
|
||||||
|
: q(manager)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgDecorationManagerV1InterfacePrivate::zxdg_decoration_manager_v1_destroy(Resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgDecorationManagerV1InterfacePrivate::zxdg_decoration_manager_v1_get_toplevel_decoration(Resource *resource,
|
||||||
|
uint32_t id,
|
||||||
|
::wl_resource *toplevelResource)
|
||||||
|
{
|
||||||
|
XdgToplevelInterfacePrivate *toplevelPrivate = XdgToplevelInterfacePrivate::get(toplevelResource);
|
||||||
|
if (!toplevelPrivate) {
|
||||||
|
wl_resource_post_error(resource->handle,
|
||||||
|
QtWaylandServer::zxdg_toplevel_decoration_v1::error_orphaned,
|
||||||
|
"no xdg-toplevel object");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toplevelPrivate->decoration) {
|
||||||
|
wl_resource_post_error(resource->handle,
|
||||||
|
QtWaylandServer::zxdg_toplevel_decoration_v1::error_already_constructed,
|
||||||
|
"decoration has been already constructed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource *decorationResource = wl_resource_create(resource->client(),
|
||||||
|
&zxdg_toplevel_decoration_v1_interface,
|
||||||
|
resource->version(), id);
|
||||||
|
|
||||||
|
auto decoration = new XdgToplevelDecorationV1Interface(toplevelPrivate->q, decorationResource);
|
||||||
|
toplevelPrivate->decoration = decoration;
|
||||||
|
|
||||||
|
emit q->decorationCreated(decoration);
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgDecorationManagerV1Interface::XdgDecorationManagerV1Interface(Display *display, QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, d(new XdgDecorationManagerV1InterfacePrivate(this))
|
||||||
|
{
|
||||||
|
d->init(*display, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgDecorationManagerV1Interface::~XdgDecorationManagerV1Interface()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgToplevelDecorationV1InterfacePrivate::XdgToplevelDecorationV1InterfacePrivate(XdgToplevelDecorationV1Interface *decoration)
|
||||||
|
: q(decoration)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgToplevelDecorationV1InterfacePrivate::zxdg_toplevel_decoration_v1_destroy_resource(Resource *resource)
|
||||||
|
{
|
||||||
|
Q_UNUSED(resource)
|
||||||
|
delete q;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgToplevelDecorationV1InterfacePrivate::zxdg_toplevel_decoration_v1_destroy(Resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgToplevelDecorationV1InterfacePrivate::zxdg_toplevel_decoration_v1_set_mode(Resource *resource, uint32_t mode)
|
||||||
|
{
|
||||||
|
Q_UNUSED(resource)
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case mode_client_side:
|
||||||
|
preferredMode = XdgToplevelDecorationV1Interface::Mode::Client;
|
||||||
|
break;
|
||||||
|
case mode_server_side:
|
||||||
|
preferredMode = XdgToplevelDecorationV1Interface::Mode::Server;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
preferredMode = XdgToplevelDecorationV1Interface::Mode::Undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit q->preferredModeChanged(preferredMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgToplevelDecorationV1InterfacePrivate::zxdg_toplevel_decoration_v1_unset_mode(Resource *resource)
|
||||||
|
{
|
||||||
|
Q_UNUSED(resource)
|
||||||
|
preferredMode = XdgToplevelDecorationV1Interface::Mode::Undefined;
|
||||||
|
emit q->preferredModeChanged(preferredMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgToplevelDecorationV1Interface::XdgToplevelDecorationV1Interface(XdgToplevelInterface *toplevel,
|
||||||
|
::wl_resource *resource)
|
||||||
|
: d(new XdgToplevelDecorationV1InterfacePrivate(this))
|
||||||
|
{
|
||||||
|
d->toplevel = toplevel;
|
||||||
|
d->init(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgToplevelDecorationV1Interface::~XdgToplevelDecorationV1Interface()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgToplevelInterface *XdgToplevelDecorationV1Interface::toplevel() const
|
||||||
|
{
|
||||||
|
return d->toplevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgToplevelDecorationV1Interface::Mode XdgToplevelDecorationV1Interface::preferredMode() const
|
||||||
|
{
|
||||||
|
return d->preferredMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgToplevelDecorationV1Interface::sendConfigure(Mode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case Mode::Client:
|
||||||
|
d->send_configure(QtWaylandServer::zxdg_toplevel_decoration_v1::mode_client_side);
|
||||||
|
break;
|
||||||
|
case Mode::Server:
|
||||||
|
d->send_configure(QtWaylandServer::zxdg_toplevel_decoration_v1::mode_server_side);
|
||||||
|
break;
|
||||||
|
case Mode::Undefined:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgToplevelDecorationV1Interface *XdgToplevelDecorationV1Interface::get(XdgToplevelInterface *toplevel)
|
||||||
|
{
|
||||||
|
XdgToplevelInterfacePrivate *toplevelPrivate = XdgToplevelInterfacePrivate::get(toplevel);
|
||||||
|
return toplevelPrivate->decoration;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace KWaylandServer
|
114
src/wayland/xdgdecoration_v1_interface.h
Normal file
114
src/wayland/xdgdecoration_v1_interface.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <KWaylandServer/kwaylandserver_export.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
struct wl_resource;
|
||||||
|
|
||||||
|
namespace KWaylandServer
|
||||||
|
{
|
||||||
|
|
||||||
|
class Display;
|
||||||
|
class XdgDecorationManagerV1InterfacePrivate;
|
||||||
|
class XdgToplevelDecorationV1Interface;
|
||||||
|
class XdgToplevelDecorationV1InterfacePrivate;
|
||||||
|
class XdgToplevelInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XdgDecorationManagerV1Interface class provides a way for the compositor and an xdg-shell
|
||||||
|
* client to negotiate the use of server-side window decorations.
|
||||||
|
*
|
||||||
|
* XdgDecorationManagerV1Interface corresponds to the interface \c zxdg_decoration_manager_v1.
|
||||||
|
*
|
||||||
|
* \since 5.20
|
||||||
|
*/
|
||||||
|
class KWAYLANDSERVER_EXPORT XdgDecorationManagerV1Interface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a decoration manager with the given \a display and \a parent.
|
||||||
|
*/
|
||||||
|
XdgDecorationManagerV1Interface(Display *display, QObject *parent = nullptr);
|
||||||
|
/**
|
||||||
|
* Destructs the XdgDecorationManagerV1Interface object.
|
||||||
|
*/
|
||||||
|
~XdgDecorationManagerV1Interface() override;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
/**
|
||||||
|
* This signal is emitted when a new \a decoration has been created.
|
||||||
|
*/
|
||||||
|
void decorationCreated(XdgToplevelDecorationV1Interface *decoration);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<XdgDecorationManagerV1InterfacePrivate> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XdgToplevelDecorationV1Interface class allows the compositor to toggle server-side window
|
||||||
|
* decoration on an xdg-toplevel surface.
|
||||||
|
*
|
||||||
|
* XdgToplevelDecorationV1Interface corresponds to the interface \c zxdg_toplevel_decoration_v1.
|
||||||
|
*
|
||||||
|
* \since 5.20
|
||||||
|
*/
|
||||||
|
class KWAYLANDSERVER_EXPORT XdgToplevelDecorationV1Interface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class Mode { Undefined, Client, Server };
|
||||||
|
Q_ENUM(Mode)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a XdgToplevelDecorationV1Interface for the given \a toplevel and initializes
|
||||||
|
* it with \a resource.
|
||||||
|
*/
|
||||||
|
XdgToplevelDecorationV1Interface(XdgToplevelInterface *toplevel, ::wl_resource *resource);
|
||||||
|
/**
|
||||||
|
* Destructs the XdgToplevelDecorationV1Interface object.
|
||||||
|
*/
|
||||||
|
~XdgToplevelDecorationV1Interface() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the toplevel for this XdgToplevelDecorationV1Interface.
|
||||||
|
*/
|
||||||
|
XdgToplevelInterface *toplevel() const;
|
||||||
|
/**
|
||||||
|
* Returns the decoration mode preferred by the client.
|
||||||
|
*/
|
||||||
|
Mode preferredMode() const;
|
||||||
|
/**
|
||||||
|
* Sends a configure event to the client. \a mode indicates the decoration mode the client
|
||||||
|
* should be using. The client must send an ack_configure in response to this event.
|
||||||
|
*
|
||||||
|
* \see XdgToplevelInterface::sendConfigure
|
||||||
|
*/
|
||||||
|
void sendConfigure(Mode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the XdgToplevelDecorationV1Interface for the specified \a toplevel.
|
||||||
|
*/
|
||||||
|
static XdgToplevelDecorationV1Interface *get(XdgToplevelInterface *toplevel);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the client has specified the preferred decoration mode. The
|
||||||
|
* compositor can decide not to use the client's mode and enforce a different mode instead.
|
||||||
|
*/
|
||||||
|
void preferredModeChanged(KWaylandServer::XdgToplevelDecorationV1Interface::Mode mode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<XdgToplevelDecorationV1InterfacePrivate> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KWaylandServer
|
44
src/wayland/xdgdecoration_v1_interface_p.h
Normal file
44
src/wayland/xdgdecoration_v1_interface_p.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xdgdecoration_v1_interface.h"
|
||||||
|
|
||||||
|
#include "qwayland-server-xdg-decoration-unstable-v1.h"
|
||||||
|
|
||||||
|
namespace KWaylandServer
|
||||||
|
{
|
||||||
|
|
||||||
|
class XdgDecorationManagerV1InterfacePrivate : public QtWaylandServer::zxdg_decoration_manager_v1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XdgDecorationManagerV1InterfacePrivate(XdgDecorationManagerV1Interface *manager);
|
||||||
|
|
||||||
|
XdgDecorationManagerV1Interface *q;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void zxdg_decoration_manager_v1_destroy(Resource *resource) override;
|
||||||
|
void zxdg_decoration_manager_v1_get_toplevel_decoration(Resource *resource, uint32_t id, ::wl_resource *toplevel) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class XdgToplevelDecorationV1InterfacePrivate : public QtWaylandServer::zxdg_toplevel_decoration_v1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XdgToplevelDecorationV1InterfacePrivate(XdgToplevelDecorationV1Interface *decoration);
|
||||||
|
|
||||||
|
XdgToplevelDecorationV1Interface *q;
|
||||||
|
XdgToplevelInterface *toplevel;
|
||||||
|
XdgToplevelDecorationV1Interface::Mode preferredMode = XdgToplevelDecorationV1Interface::Mode::Undefined;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void zxdg_toplevel_decoration_v1_destroy_resource(Resource *resource) override;
|
||||||
|
void zxdg_toplevel_decoration_v1_destroy(Resource *resource) override;
|
||||||
|
void zxdg_toplevel_decoration_v1_set_mode(Resource *resource, uint32_t mode) override;
|
||||||
|
void zxdg_toplevel_decoration_v1_unset_mode(Resource *resource) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KWaylandServer
|
File diff suppressed because it is too large
Load diff
|
@ -1,509 +1,533 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
*/
|
*/
|
||||||
#ifndef KWAYLAND_SERVER_XDGSHELL_INTERFACE_H
|
|
||||||
#define KWAYLAND_SERVER_XDGSHELL_INTERFACE_H
|
|
||||||
|
|
||||||
#include "global.h"
|
#pragma once
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#include <QSize>
|
|
||||||
|
|
||||||
#include <KWaylandServer/kwaylandserver_export.h>
|
#include <KWaylandServer/kwaylandserver_export.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QSharedDataPointer>
|
||||||
|
|
||||||
|
struct wl_resource;
|
||||||
|
|
||||||
namespace KWaylandServer
|
namespace KWaylandServer
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class Display;
|
||||||
class OutputInterface;
|
class OutputInterface;
|
||||||
class SeatInterface;
|
class SeatInterface;
|
||||||
class SurfaceInterface;
|
class SurfaceInterface;
|
||||||
class XdgShellPopupInterface;
|
class XdgShellInterfacePrivate;
|
||||||
class XdgShellSurfaceInterface;
|
class XdgSurfaceInterfacePrivate;
|
||||||
template <typename T>
|
class XdgToplevelInterfacePrivate;
|
||||||
class GenericShellSurface;
|
class XdgPopupInterfacePrivate;
|
||||||
|
class XdgPositionerData;
|
||||||
|
class XdgToplevelInterface;
|
||||||
|
class XdgPopupInterface;
|
||||||
|
class XdgSurfaceInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum describing the different InterfaceVersion encapsulated in this implementation.
|
* The XdgShellInterface class represents an extension for destrop-style user interfaces.
|
||||||
*
|
*
|
||||||
* @since 5.25
|
* The XdgShellInterface class provides a way for a client to extend a regular Wayland surface
|
||||||
**/
|
* with functionality required to construct user interface elements, e.g. toplevel windows or
|
||||||
enum class XdgShellInterfaceVersion
|
* menus.
|
||||||
{
|
*
|
||||||
/**
|
* XdgShellInterface corresponds to the WaylandInterface \c xdg_wm_base.
|
||||||
* xdg_shell (unstable v5)
|
*
|
||||||
**/
|
* \since 5.20
|
||||||
UnstableV5,
|
|
||||||
/**
|
|
||||||
* zxdg_shell_v6 (unstable v6)
|
|
||||||
* @since 5.39
|
|
||||||
**/
|
|
||||||
UnstableV6,
|
|
||||||
/**
|
|
||||||
xdg_wm_base (stable)
|
|
||||||
@since 5.48
|
|
||||||
*/
|
|
||||||
Stable
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flags describing how a popup should be reposition if constrained
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
enum class PositionerConstraint {
|
class KWAYLANDSERVER_EXPORT XdgShellInterface : public QObject
|
||||||
/**
|
|
||||||
* Slide the popup on the X axis until there is room
|
|
||||||
*/
|
|
||||||
SlideX = 1 << 0,
|
|
||||||
/**
|
|
||||||
* Slide the popup on the Y axis until there is room
|
|
||||||
*/
|
|
||||||
SlideY = 1 << 1,
|
|
||||||
/**
|
|
||||||
* Invert the anchor and gravity on the X axis
|
|
||||||
*/
|
|
||||||
FlipX = 1 << 2,
|
|
||||||
/**
|
|
||||||
* Invert the anchor and gravity on the Y axis
|
|
||||||
*/
|
|
||||||
FlipY = 1 << 3,
|
|
||||||
/**
|
|
||||||
* Resize the popup in the X axis
|
|
||||||
*/
|
|
||||||
ResizeX = 1 << 4,
|
|
||||||
/**
|
|
||||||
* Resize the popup in the Y axis
|
|
||||||
*/
|
|
||||||
ResizeY = 1 << 5
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(PositionerConstraints, PositionerConstraint)
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @since 5.25
|
|
||||||
**/
|
|
||||||
class KWAYLANDSERVER_EXPORT XdgShellInterface : public Global
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~XdgShellInterface();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns The interface version used by this XdgShellInterface
|
* Constructs an XdgShellInterface object with the given wayland display \a display.
|
||||||
**/
|
|
||||||
XdgShellInterfaceVersion interfaceVersion() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns The XdgShellSurfaceInterface for the @p native resource.
|
|
||||||
**/
|
|
||||||
//TODO KF6 make virtual
|
|
||||||
XdgShellSurfaceInterface *getSurface(wl_resource *native);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Confirm the client is still alive and responding
|
|
||||||
*
|
|
||||||
* Will result in pong being emitted
|
|
||||||
*
|
|
||||||
* @returns unique identifier for this request
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
quint32 ping(XdgShellSurfaceInterface * surface);
|
XdgShellInterface(Display *display, QObject *parent = nullptr);
|
||||||
|
/**
|
||||||
|
* Destructs the XdgShellInterface object.
|
||||||
|
*/
|
||||||
|
~XdgShellInterface() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the wayland display of the XdgShellInterface.
|
||||||
|
*/
|
||||||
|
Display *display() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a ping event to the client with the given xdg-surface \a surface. If the client
|
||||||
|
* replies to the event within a reasonable amount of time, pongReceived signal will be
|
||||||
|
* emitted.
|
||||||
|
*/
|
||||||
|
quint32 ping(XdgSurfaceInterface *surface);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void surfaceCreated(KWaylandServer::XdgShellSurfaceInterface *surface);
|
/**
|
||||||
|
* This signal is emitted when a new XdgToplevelInterface object is created.
|
||||||
|
*/
|
||||||
|
void toplevelCreated(XdgToplevelInterface *toplevel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted whenever a new popup got created.
|
* This signal is emitted when a new XdgPopupInterface object is created.
|
||||||
*
|
|
||||||
* A popup only gets created in response to an action on the @p seat.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param surface The popup xdg shell surface which got created
|
|
||||||
* @param seat The seat on which an action triggered the popup
|
|
||||||
* @param serial The serial of the action on the seat
|
|
||||||
*
|
|
||||||
* XDGV5 only
|
|
||||||
* Use both xdgPopupCreated and XdgShellPopupInterface::grabbed to cover both XDGV5 and XDGV6
|
|
||||||
**/
|
|
||||||
|
|
||||||
void popupCreated(KWaylandServer::XdgShellPopupInterface *surface, KWaylandServer::SeatInterface *seat, quint32 serial);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Emitted whenever a new popup gets created.
|
|
||||||
*
|
|
||||||
* @param surface The popup xdg shell surface which got created
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
void xdgPopupCreated(KWaylandServer::XdgShellPopupInterface *surface);
|
void popupCreated(XdgPopupInterface *popup);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Emitted in response to a ping request
|
* This signal is emitted when the client has responded to a ping event with serial \a serial.
|
||||||
*
|
|
||||||
* @param serial unique identifier for the request
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
void pongReceived(quint32 serial);
|
void pongReceived(quint32 serial);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Emitted when the application takes more than expected
|
* @todo Drop this signal.
|
||||||
* to answer to a ping, this will always be emitted before
|
|
||||||
* eventuallt pingTimeout gets emitted
|
|
||||||
*
|
*
|
||||||
* @param serial unique identifier for the request
|
* This signal is emitted when the client has not responded to a ping event with serial
|
||||||
* @since 5.39
|
* \a serial within a reasonable amount of time and the compositor gave up on it.
|
||||||
*/
|
|
||||||
void pingDelayed(quint32 serial);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Emitted when the application doesn't answer to a ping
|
|
||||||
* and the serve gave up on it
|
|
||||||
*
|
|
||||||
* @param serial unique identifier for the request
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
void pingTimeout(quint32 serial);
|
void pingTimeout(quint32 serial);
|
||||||
|
|
||||||
protected:
|
/**
|
||||||
class Private;
|
* This signal is emitted when the client has not responded to a ping event with serial
|
||||||
explicit XdgShellInterface(Private *d, QObject *parent = nullptr);
|
* \a serial within a reasonable amount of time.
|
||||||
|
*/
|
||||||
|
void pingDelayed(quint32 serial);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Private *d_func() const;
|
QScopedPointer<XdgShellInterfacePrivate> d;
|
||||||
|
friend class XdgShellInterfacePrivate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The XdgSurfaceInterface class provides a base set of functionality required to construct
|
||||||
|
* user interface elements.
|
||||||
*
|
*
|
||||||
* @since 5.25
|
* XdgSurfaceInterface corresponds to the Wayland interface \c xdg_surface.
|
||||||
**/
|
*
|
||||||
class KWAYLANDSERVER_EXPORT XdgShellSurfaceInterface : public Resource
|
* \since 5.20
|
||||||
|
*/
|
||||||
|
class KWAYLANDSERVER_EXPORT XdgSurfaceInterface : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~XdgShellSurfaceInterface();
|
/**
|
||||||
|
* Constructs an XdgSurfaceInterface for the given \a shell and \a surface.
|
||||||
|
*/
|
||||||
|
XdgSurfaceInterface(XdgShellInterface *shell, SurfaceInterface *surface,
|
||||||
|
::wl_resource *resource);
|
||||||
|
/**
|
||||||
|
* Destructs the XdgSurfaceInterface object.
|
||||||
|
*/
|
||||||
|
~XdgSurfaceInterface() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns The interface version used by this XdgShellSurfaceInterface
|
* Returns the XdgToplevelInterface associated with this XdgSurfaceInterface.
|
||||||
**/
|
|
||||||
XdgShellInterfaceVersion interfaceVersion() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* States the Surface can be in
|
|
||||||
**/
|
|
||||||
enum class State {
|
|
||||||
/**
|
|
||||||
* The Surface is maximized.
|
|
||||||
**/
|
|
||||||
Maximized = 1 << 0,
|
|
||||||
/**
|
|
||||||
* The Surface is fullscreen.
|
|
||||||
**/
|
|
||||||
Fullscreen = 1 << 1,
|
|
||||||
/**
|
|
||||||
* The Surface is currently being resized by the Compositor.
|
|
||||||
**/
|
|
||||||
Resizing = 1 << 2,
|
|
||||||
/**
|
|
||||||
* The Surface is considered active. Does not imply keyboard focus.
|
|
||||||
**/
|
|
||||||
Activated = 1 << 3
|
|
||||||
};
|
|
||||||
Q_DECLARE_FLAGS(States, State)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a configure event to the Surface.
|
|
||||||
* This tells the Surface the current @p states it is in and the @p size it should have.
|
|
||||||
* If @p size has width and height at @c 0, the Surface can choose the size.
|
|
||||||
*
|
*
|
||||||
* The Surface acknowledges the configure event with {@link configureAcknowledged}.
|
* This method will return \c null if no xdg_toplevel object is associated with this surface.
|
||||||
|
*/
|
||||||
|
XdgToplevelInterface *toplevel() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the XdgPopupInterface associated with this XdgSurfaceInterface.
|
||||||
*
|
*
|
||||||
* @param states The states the surface is in
|
* This method will return \c null if no xdg_popup object is associated with this surface.
|
||||||
* @param size The requested size
|
*/
|
||||||
* @returns The serial of the configure event
|
XdgPopupInterface *popup() const;
|
||||||
* @see configureAcknowledged
|
|
||||||
* @see isConfigurePending
|
|
||||||
**/
|
|
||||||
quint32 configure(States states, const QSize &size = QSize(0, 0));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns @c true if there is a not yet acknowledged configure event.
|
* Returns the XdgShellInterface associated with this XdgSurfaceInterface.
|
||||||
* @see configure
|
*/
|
||||||
* @see configureAcknowledged
|
XdgShellInterface *shell() const;
|
||||||
**/
|
|
||||||
bool isConfigurePending() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The SurfaceInterface this XdgSurfaceV5Interface got created for.
|
* Returns the SurfaceInterface assigned to this XdgSurfaceInterface.
|
||||||
**/
|
*/
|
||||||
SurfaceInterface *surface() const;
|
SurfaceInterface *surface() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns The title of this surface.
|
* Returns \c true if the surface has been configured; otherwise returns \c false.
|
||||||
* @see titleChanged
|
*/
|
||||||
**/
|
bool isConfigured() const;
|
||||||
QString title() const;
|
|
||||||
QByteArray windowClass() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns Whether this Surface is a transient for another Surface, that is it has a parent.
|
* Returns the window geometry of the XdgSurfaceInterface.
|
||||||
* @see transientFor
|
|
||||||
**/
|
|
||||||
bool isTransient() const;
|
|
||||||
/**
|
|
||||||
* @returns the parent surface if the surface is a transient for another surface
|
|
||||||
* @see isTransient
|
|
||||||
**/
|
|
||||||
QPointer<XdgShellSurfaceInterface> transientFor() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request the client to close the window.
|
|
||||||
**/
|
|
||||||
void close();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief windowGeometry
|
|
||||||
* The geometry of the window within the buffer
|
|
||||||
*
|
*
|
||||||
* If invalid, the geometry of the bufer should be used instead
|
* This method will return an invalid QRect if the window geometry is not set by the client.
|
||||||
* @since 5.59
|
|
||||||
*/
|
*/
|
||||||
QRect windowGeometry() const;
|
QRect windowGeometry() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns The minimum size for the window specified by the client.
|
* Returns the XdgSurfaceInterface for the specified wayland resource object \a resource.
|
||||||
* @since 5.65
|
*/
|
||||||
|
static XdgSurfaceInterface *get(::wl_resource *resource);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
/**
|
||||||
|
* This signal is emitted when a configure event with serial \a serial has been acknowledged.
|
||||||
|
*/
|
||||||
|
void configureAcknowledged(quint32 serial);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the window geometry has been changed.
|
||||||
|
*/
|
||||||
|
void windowGeometryChanged(const QRect &rect);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<XdgSurfaceInterfacePrivate> d;
|
||||||
|
friend class XdgSurfaceInterfacePrivate;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XdgToplevelInterface class represents a surface with window-like functionality such
|
||||||
|
* as maximize, fullscreen, resizing, minimizing, etc.
|
||||||
|
*
|
||||||
|
* XdgToplevelInterface corresponds to the Wayland interface \c xdg_toplevel.
|
||||||
|
*
|
||||||
|
* \since 5.20
|
||||||
|
*/
|
||||||
|
class KWAYLANDSERVER_EXPORT XdgToplevelInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum State {
|
||||||
|
MaximizedHorizontal = 0x1,
|
||||||
|
MaximizedVertical = 0x2,
|
||||||
|
FullScreen = 0x4,
|
||||||
|
Resizing = 0x8,
|
||||||
|
Activated = 0x10,
|
||||||
|
Maximized = MaximizedHorizontal | MaximizedVertical
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(States, State)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an XdgToplevelInterface for the given xdg-surface \a surface.
|
||||||
|
*/
|
||||||
|
XdgToplevelInterface(XdgSurfaceInterface *surface, ::wl_resource *resource);
|
||||||
|
/**
|
||||||
|
* Destructs the XdgToplevelInterface object.
|
||||||
|
*/
|
||||||
|
~XdgToplevelInterface() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the XdgShellInterface for this XdgToplevelInterface.
|
||||||
|
*
|
||||||
|
* This is equivalent to xdgSurface()->shell().
|
||||||
|
*/
|
||||||
|
XdgShellInterface *shell() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the XdgSurfaceInterface associated with the XdgToplevelInterface.
|
||||||
|
*/
|
||||||
|
XdgSurfaceInterface *xdgSurface() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the SurfaceInterface associated with the XdgToplevelInterface.
|
||||||
|
*/
|
||||||
|
SurfaceInterface *surface() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parent XdgToplevelInterface above which this toplevel is stacked.
|
||||||
|
*/
|
||||||
|
XdgToplevelInterface *parentXdgToplevel() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns \c true if the toplevel has been configured; otherwise returns \c false.
|
||||||
|
*/
|
||||||
|
bool isConfigured() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the window title of the toplevel surface.
|
||||||
|
*/
|
||||||
|
QString windowTitle() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the window class of the toplevel surface.
|
||||||
|
*/
|
||||||
|
QString windowClass() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the minimum window geometry size of the toplevel surface.
|
||||||
*/
|
*/
|
||||||
QSize minimumSize() const;
|
QSize minimumSize() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns The maximum size for the window specified by the client.
|
* Returns the maximum window geometry size of the toplevel surface.
|
||||||
* @since 5.65
|
|
||||||
*/
|
*/
|
||||||
QSize maximumSize() const;
|
QSize maximumSize() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a configure event to the client. \a size specifies the new window geometry size. A size
|
||||||
|
* of zero means the client should decide its own window dimensions.
|
||||||
|
*/
|
||||||
|
quint32 sendConfigure(const QSize &size, const States &states);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a close event to the client. The client may choose to ignore this request.
|
||||||
|
*/
|
||||||
|
void sendClose();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the XdgToplevelInterface for the specified wayland resource object \a resource.
|
||||||
|
*/
|
||||||
|
static XdgToplevelInterface *get(::wl_resource *resource);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* Emitted whenever the title changes.
|
* This signal is emitted when the xdg-toplevel has commited the initial state and wants to
|
||||||
*
|
* be configured. After initializing the toplevel, you must send a configure event.
|
||||||
* @see title
|
*/
|
||||||
**/
|
void initializeRequested();
|
||||||
void titleChanged(const QString&);
|
|
||||||
/**
|
/**
|
||||||
* Emitted whenever the window class changes.
|
* This signal is emitted when the toplevel's title has been changed.
|
||||||
*
|
*/
|
||||||
* @see windowClass
|
void windowTitleChanged(const QString &windowTitle);
|
||||||
**/
|
|
||||||
void windowClassChanged(const QByteArray&);
|
|
||||||
/**
|
/**
|
||||||
* The surface requested a window move.
|
* This signal is emitted when the toplevel's application id has been changed.
|
||||||
*
|
*/
|
||||||
* @param seat The SeatInterface on which the surface requested the move
|
void windowClassChanged(const QString &windowClass);
|
||||||
* @param serial The serial of the implicit mouse grab which triggered the move
|
|
||||||
**/
|
/**
|
||||||
|
* This signal is emitted when the toplevel has requested the window menu to be shown at
|
||||||
|
* \a pos. The \a seat and the \a serial indicate the user action that triggerred the request.
|
||||||
|
*/
|
||||||
|
void windowMenuRequested(KWaylandServer::SeatInterface *seat, const QPoint &pos, quint32 serial);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the toplevel's minimum size has been changed.
|
||||||
|
*/
|
||||||
|
void minimumSizeChanged(const QSize &size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the toplevel's maximum size has been changed.
|
||||||
|
*/
|
||||||
|
void maximumSizeChanged(const QSize &size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the toplevel wants to be interactively moved. The \a seat and
|
||||||
|
* the \a serial indicate the user action in response to which this request has been issued.
|
||||||
|
*/
|
||||||
void moveRequested(KWaylandServer::SeatInterface *seat, quint32 serial);
|
void moveRequested(KWaylandServer::SeatInterface *seat, quint32 serial);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The surface requested a window resize.
|
* This signal is emitted when the toplevel wants to be interactively resized along the
|
||||||
*
|
* specified window edges \a edges. The \a seat and the \a serial indicate the user action
|
||||||
* @param seat The SeatInterface on which the surface requested the resize
|
* in response to which this request has been issued.
|
||||||
* @param serial The serial of the implicit mouse grab which triggered the resize
|
*/
|
||||||
* @param edges A hint which edges are involved in the resize
|
void resizeRequested(KWaylandServer::SeatInterface *seat, Qt::Edges edges, quint32 serial);
|
||||||
**/
|
|
||||||
void resizeRequested(KWaylandServer::SeatInterface *seat, quint32 serial, Qt::Edges edges);
|
|
||||||
void windowMenuRequested(KWaylandServer::SeatInterface *seat, quint32 serial, const QPoint &surfacePos);
|
|
||||||
/**
|
/**
|
||||||
* The surface requested a change of maximized state.
|
* This signal is emitted when the toplevel surface wants to become maximized.
|
||||||
* @param maximized Whether the window wants to be maximized
|
*/
|
||||||
**/
|
void maximizeRequested();
|
||||||
void maximizedChanged(bool maximized);
|
|
||||||
/**
|
/**
|
||||||
* The surface requested a change of fullscreen state
|
* This signal is emitted when the toplevel surface wants to become unmaximized.
|
||||||
* @param fullscreen Whether the window wants to be fullscreen
|
*/
|
||||||
* @param output An optional output hint on which the window wants to be fullscreen
|
void unmaximizeRequested();
|
||||||
**/
|
|
||||||
void fullscreenChanged(bool fullscreen, KWaylandServer::OutputInterface *output);
|
|
||||||
/**
|
/**
|
||||||
* The surface requested to be minimized.
|
* This signal is emitted when the toplevel wants to be shown in the full screen mode.
|
||||||
**/
|
*/
|
||||||
|
void fullscreenRequested(KWaylandServer::OutputInterface *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the toplevel surface wants to leave the full screen mode.
|
||||||
|
*/
|
||||||
|
void unfullscreenRequested();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the toplevel wants to be iconified.
|
||||||
|
*/
|
||||||
void minimizeRequested();
|
void minimizeRequested();
|
||||||
/**
|
|
||||||
* A configure event with @p serial got acknowledged.
|
|
||||||
* @see configure
|
|
||||||
**/
|
|
||||||
void configureAcknowledged(quint32 serial);
|
|
||||||
/**
|
|
||||||
* Emitted whenever the parent surface changes.
|
|
||||||
* @see isTransient
|
|
||||||
* @see transientFor
|
|
||||||
**/
|
|
||||||
void transientForChanged();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted whenever the maximum size hint changes
|
* This signal is emitted when the parent toplevel has changed.
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
void maxSizeChanged(const QSize &size);
|
void parentXdgToplevelChanged();
|
||||||
|
|
||||||
/**
|
|
||||||
* Emitted whenever the minimum size hint changes
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
|
||||||
void minSizeChanged(const QSize &size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief windowGeometryChanged
|
|
||||||
* @param windowGeometry the newly changed windowGeometry
|
|
||||||
* @since 5.59
|
|
||||||
*/
|
|
||||||
void windowGeometryChanged(const QRect &windowGeometry);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class Private;
|
|
||||||
explicit XdgShellSurfaceInterface(Private *p);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Private *d_func() const;
|
QScopedPointer<XdgToplevelInterfacePrivate> d;
|
||||||
friend class GenericShellSurface<XdgShellSurfaceInterface>;
|
friend class XdgToplevelInterfacePrivate;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The XdgPositioner class provides a collection of rules for the placement of a popup surface.
|
||||||
*
|
*
|
||||||
* @since 5.25
|
* XdgPositioner corresponds to the Wayland interface \c xdg_positioner.
|
||||||
**/
|
*
|
||||||
class KWAYLANDSERVER_EXPORT XdgShellPopupInterface : public Resource
|
* \since 5.20
|
||||||
|
*/
|
||||||
|
class KWAYLANDSERVER_EXPORT XdgPositioner
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
virtual ~XdgShellPopupInterface();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The SurfaceInterface this XdgShellPopupInterface got created for.
|
* Constructs an incomplete XdgPositioner object.
|
||||||
**/
|
|
||||||
SurfaceInterface *surface() const;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ask the popup surface to configure itself for the given configuration.
|
|
||||||
*
|
|
||||||
* @arg rect. The position of the surface relative to the transient parent
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
quint32 configure(const QRect &rect);
|
XdgPositioner();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns the parent surface.
|
* Constructs a copy of the XdgPositioner object.
|
||||||
* @see transientOffset
|
|
||||||
**/
|
|
||||||
QPointer<SurfaceInterface> transientFor() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The offset of the Surface in the coordinate system of the SurfaceInterface this surface is a transient for.
|
|
||||||
*
|
|
||||||
* For XDG V6 this returns the point on the anchorRect defined by the anchor edge.
|
|
||||||
*
|
|
||||||
* @returns offset in parent coordinate system.
|
|
||||||
* @see transientFor
|
|
||||||
**/
|
|
||||||
QPoint transientOffset() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size of the surface that is to be positioned.
|
|
||||||
*
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
QSize initialSize() const;
|
XdgPositioner(const XdgPositioner &other);
|
||||||
|
/**
|
||||||
|
* Destructs the XdgPositioner object.
|
||||||
|
*/
|
||||||
|
~XdgPositioner();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The area this popup should be positioned around
|
* Assigns the value of \a other to this XdgPositioner object.
|
||||||
* @since 5.39
|
*/
|
||||||
|
XdgPositioner &operator=(const XdgPositioner &other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns \c true if the positioner object is complete; otherwise returns \c false.
|
||||||
|
*
|
||||||
|
* An xdg positioner considered complete if it has a valid size and a valid anchor rect.
|
||||||
|
*/
|
||||||
|
bool isComplete() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of orientations along which the compositor may slide the popup to ensure
|
||||||
|
* that it is entirely inside the compositor's defined "work area."
|
||||||
|
*/
|
||||||
|
Qt::Orientations slideConstraintAdjustments() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of orientations along which the compositor may flip the popup to ensure
|
||||||
|
* that it is entirely inside the compositor's defined "work area."
|
||||||
|
*/
|
||||||
|
Qt::Orientations flipConstraintAdjustments() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of orientations along which the compositor can resize the popup to ensure
|
||||||
|
* that it is entirely inside the compositor's defined "work area."
|
||||||
|
*/
|
||||||
|
Qt::Orientations resizeConstraintAdjustments() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of edges on the anchor rectangle that the surface should be positioned
|
||||||
|
* around.
|
||||||
|
*/
|
||||||
|
Qt::Edges anchorEdges() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the direction in which the surface should be positioned, relative to the anchor
|
||||||
|
* point of the parent surface.
|
||||||
|
*/
|
||||||
|
Qt::Edges gravityEdges() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the window geometry size of the surface that is to be positioned.
|
||||||
|
*/
|
||||||
|
QSize size() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the anchor rectangle relative to the upper left corner of the window geometry of
|
||||||
|
* the parent surface that the popup should be positioned around.
|
||||||
*/
|
*/
|
||||||
QRect anchorRect() const;
|
QRect anchorRect() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which edge of the anchor should the popup be positioned around
|
* Returns the surface position offset relative to the position of the anchor on the anchor
|
||||||
* @since 5.39
|
* rectangle and the anchor on the surface.
|
||||||
*/
|
*/
|
||||||
Qt::Edges anchorEdge() const;
|
QPoint offset() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An additional offset that should be applied to the popup from the anchor rect
|
* Returns the current state of the xdg positioner object identified by \a resource.
|
||||||
|
*/
|
||||||
|
static XdgPositioner get(::wl_resource *resource);
|
||||||
|
|
||||||
|
private:
|
||||||
|
XdgPositioner(const QSharedDataPointer<XdgPositionerData> &data);
|
||||||
|
QSharedDataPointer<XdgPositionerData> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XdgPopupInterface class represents a surface that can be used to implement context menus,
|
||||||
|
* popovers and other similar short-lived user interface elements.
|
||||||
|
*
|
||||||
|
* XdgPopupInterface corresponds to the Wayland interface \c xdg_popup.
|
||||||
|
*
|
||||||
|
* \since 5.20
|
||||||
|
*/
|
||||||
|
class KWAYLANDSERVER_EXPORT XdgPopupInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
XdgPopupInterface(XdgSurfaceInterface *surface, XdgSurfaceInterface *parentSurface,
|
||||||
|
const XdgPositioner &positioner, ::wl_resource *resource);
|
||||||
|
/**
|
||||||
|
* Destructs the XdgPopupInterface object.
|
||||||
|
*/
|
||||||
|
~XdgPopupInterface() override;
|
||||||
|
|
||||||
|
XdgShellInterface *shell() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parent XdgSurfaceInterface.
|
||||||
*
|
*
|
||||||
* @since 5.39
|
* This method may return \c null, in which case the parent xdg-surface must be specified
|
||||||
|
* using "some other protocol", before commiting the initial state.
|
||||||
*/
|
*/
|
||||||
QPoint anchorOffset() const;
|
XdgSurfaceInterface *parentXdgSurface() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies in what direction the popup should be positioned around the anchor
|
* Returns the XdgSurfaceInterface associated with the XdgPopupInterface.
|
||||||
* i.e if the gravity is "bottom", then then the top of top of the popup will be at the anchor edge
|
|
||||||
* if the gravity is top, then the bottom of the popup will be at the anchor edge
|
|
||||||
*
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
|
XdgSurfaceInterface *xdgSurface() const;
|
||||||
//DAVE left + right is illegal, so this is possible a useless return value? Maybe an enum with 9 entries left, topleft, top, ..
|
|
||||||
Qt::Edges gravity() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies how the compositor should position the popup if it does not fit in the requested position
|
* Returns the SurfaceInterface associated with the XdgPopupInterface.
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
PositionerConstraints constraintAdjustments() const;
|
SurfaceInterface *surface() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dismiss this popup. This indicates to the client that it should destroy this popup.
|
* Returns the XdgPositioner assigned to this XdgPopupInterface.
|
||||||
* The Compositor can invoke this method when e.g. the user clicked outside the popup
|
*/
|
||||||
* to dismiss it.
|
XdgPositioner positioner() const;
|
||||||
**/
|
|
||||||
void popupDone();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief windowGeometryChanged
|
* Returns \c true if the popup has been configured; otherwise returns \c false.
|
||||||
* @param windowGeometry the newly changed geometry of the window contents within the buffer
|
|
||||||
* @since 5.59
|
|
||||||
*/
|
*/
|
||||||
QRect windowGeometry()const;
|
bool isConfigured() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a configure event to the client and returns the serial number of the event.
|
||||||
|
*/
|
||||||
|
quint32 sendConfigure(const QRect &rect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a popup done event to the client.
|
||||||
|
*/
|
||||||
|
void sendPopupDone();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the XdgPopupInterface for the specified wayland resource object \a resource.
|
||||||
|
*/
|
||||||
|
static XdgPopupInterface *get(::wl_resource *resource);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* A configure event with @p serial got acknowledged.
|
* This signal is emitted when the xdg-popup has commited the initial state and wants to
|
||||||
* Note: XdgV6 only
|
* be configured. After initializing the popup, you must send a configure event.
|
||||||
* @see configure
|
|
||||||
* @since 5.39
|
|
||||||
**/
|
|
||||||
void configureAcknowledged(quint32 serial);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The client requested that this popup takes an explicit grab
|
|
||||||
*
|
|
||||||
* @param seat The seat on which an action triggered the popup
|
|
||||||
* @param serial The serial of the action on the seat
|
|
||||||
* @since 5.39
|
|
||||||
*/
|
*/
|
||||||
void grabRequested(KWaylandServer::SeatInterface *seat, quint32 serial);
|
void initializeRequested();
|
||||||
|
void grabRequested(SeatInterface *seat, quint32 serial);
|
||||||
/**
|
|
||||||
* @brief windowGeometryChanged
|
|
||||||
* @param windowGeometry the newly changed windowGeometry
|
|
||||||
* @since 5.59
|
|
||||||
*/
|
|
||||||
void windowGeometryChanged(const QRect &windowGeometry);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class Private;
|
|
||||||
explicit XdgShellPopupInterface(Private *p);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class GenericShellSurface<XdgShellPopupInterface>;
|
QScopedPointer<XdgPopupInterfacePrivate> d;
|
||||||
|
|
||||||
Private *d_func() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace KWaylandServer
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(KWaylandServer::XdgShellSurfaceInterface *)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(KWaylandServer::XdgToplevelInterface::States)
|
||||||
Q_DECLARE_METATYPE(KWaylandServer::XdgShellPopupInterface *)
|
Q_DECLARE_METATYPE(KWaylandServer::XdgToplevelInterface::State)
|
||||||
Q_DECLARE_METATYPE(KWaylandServer::XdgShellSurfaceInterface::State)
|
Q_DECLARE_METATYPE(KWaylandServer::XdgToplevelInterface::States)
|
||||||
Q_DECLARE_METATYPE(KWaylandServer::XdgShellSurfaceInterface::States)
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(KWaylandServer::PositionerConstraints)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,94 +1,175 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
*/
|
*/
|
||||||
#ifndef KWAYLAND_SERVER_XDGSHELL_INTERFACE_P_H
|
|
||||||
#define KWAYLAND_SERVER_XDGSHELL_INTERFACE_P_H
|
|
||||||
#include "xdgshell_interface.h"
|
|
||||||
#include "global_p.h"
|
|
||||||
#include "generic_shell_surface_p.h"
|
|
||||||
#include "resource_p.h"
|
|
||||||
|
|
||||||
#include <QTimer>
|
#pragma once
|
||||||
|
|
||||||
|
#include "xdgshell_interface.h"
|
||||||
|
#include "qwayland-server-xdg-shell.h"
|
||||||
|
|
||||||
|
#include "surface_interface.h"
|
||||||
|
#include "surfacerole_p.h"
|
||||||
|
|
||||||
namespace KWaylandServer
|
namespace KWaylandServer
|
||||||
{
|
{
|
||||||
|
|
||||||
class XdgShellInterface::Private : public Global::Private
|
class XdgToplevelDecorationV1Interface;
|
||||||
|
|
||||||
|
class XdgShellInterfacePrivate : public QtWaylandServer::xdg_wm_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XdgShellInterfaceVersion interfaceVersion;
|
XdgShellInterfacePrivate(XdgShellInterface *shell);
|
||||||
|
|
||||||
virtual quint32 ping(XdgShellSurfaceInterface * surface) = 0;
|
void registerXdgSurface(XdgSurfaceInterface *surface);
|
||||||
void setupTimer(quint32 serial);
|
void unregisterXdgSurface(XdgSurfaceInterface *surface);
|
||||||
//pingserial/timer correspondence
|
|
||||||
QHash <quint32, QTimer *> pingTimers;
|
void registerPing(quint32 serial);
|
||||||
|
|
||||||
|
static XdgShellInterfacePrivate *get(XdgShellInterface *shell);
|
||||||
|
|
||||||
protected:
|
|
||||||
Private(XdgShellInterfaceVersion interfaceVersion, XdgShellInterface *q, Display *d, const wl_interface *interface, quint32 version);
|
|
||||||
XdgShellInterface *q;
|
XdgShellInterface *q;
|
||||||
};
|
Display *display;
|
||||||
|
QMap<quint32, QTimer *> pings;
|
||||||
class XdgShellSurfaceInterface::Private : public Resource::Private, public GenericShellSurface<XdgShellSurfaceInterface>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~Private();
|
|
||||||
|
|
||||||
virtual void close() = 0;
|
|
||||||
virtual quint32 configure(States states, const QSize &size) = 0;
|
|
||||||
virtual QRect windowGeometry() const = 0;
|
|
||||||
virtual QSize minimumSize() const = 0;
|
|
||||||
virtual QSize maximumSize() const = 0;
|
|
||||||
|
|
||||||
XdgShellSurfaceInterface *q_func() {
|
|
||||||
return reinterpret_cast<XdgShellSurfaceInterface *>(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<quint32> configureSerials;
|
|
||||||
QPointer<XdgShellSurfaceInterface> parent;
|
|
||||||
XdgShellInterfaceVersion interfaceVersion;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Private(XdgShellInterfaceVersion interfaceVersion, XdgShellSurfaceInterface *q, Global *c, SurfaceInterface *surface, wl_resource *parentResource, const wl_interface *interface, const void *implementation);
|
void xdg_wm_base_destroy(Resource *resource) override;
|
||||||
|
void xdg_wm_base_create_positioner(Resource *resource, uint32_t id) override;
|
||||||
|
void xdg_wm_base_get_xdg_surface(Resource *resource, uint32_t id, ::wl_resource *surface) override;
|
||||||
|
void xdg_wm_base_pong(Resource *resource, uint32_t serial) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMultiMap<wl_client *, XdgSurfaceInterface *> xdgSurfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XdgShellPopupInterface::Private : public Resource::Private, public GenericShellSurface<XdgShellPopupInterface>
|
class XdgPositionerData : public QSharedData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Private();
|
Qt::Orientations slideConstraintAdjustments;
|
||||||
virtual void popupDone() = 0;
|
Qt::Orientations flipConstraintAdjustments;
|
||||||
virtual QRect windowGeometry() const = 0;
|
Qt::Orientations resizeConstraintAdjustments;
|
||||||
|
Qt::Edges anchorEdges;
|
||||||
|
Qt::Edges gravityEdges;
|
||||||
|
QPoint offset;
|
||||||
|
QSize size;
|
||||||
|
QRect anchorRect;
|
||||||
|
};
|
||||||
|
|
||||||
XdgShellPopupInterface *q_func() {
|
class XdgPositionerPrivate : public QtWaylandServer::xdg_positioner
|
||||||
return reinterpret_cast<XdgShellPopupInterface *>(q);
|
{
|
||||||
}
|
public:
|
||||||
|
XdgPositionerPrivate(::wl_resource *resource);
|
||||||
|
|
||||||
virtual quint32 configure(const QRect &rect) {
|
QSharedDataPointer<XdgPositionerData> data;
|
||||||
Q_UNUSED(rect)
|
|
||||||
return 0;
|
static XdgPositionerPrivate *get(::wl_resource *resource);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void xdg_positioner_destroy_resource(Resource *resource) override;
|
||||||
|
void xdg_positioner_destroy(Resource *resource) override;
|
||||||
|
void xdg_positioner_set_size(Resource *resource, int32_t width, int32_t height) override;
|
||||||
|
void xdg_positioner_set_anchor_rect(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) override;
|
||||||
|
void xdg_positioner_set_anchor(Resource *resource, uint32_t anchor) override;
|
||||||
|
void xdg_positioner_set_gravity(Resource *resource, uint32_t gravity) override;
|
||||||
|
void xdg_positioner_set_constraint_adjustment(Resource *resource, uint32_t constraint_adjustment) override;
|
||||||
|
void xdg_positioner_set_offset(Resource *resource, int32_t x, int32_t y) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class XdgSurfaceInterfacePrivate : public QtWaylandServer::xdg_surface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XdgSurfaceInterfacePrivate(XdgSurfaceInterface *xdgSurface);
|
||||||
|
|
||||||
|
void commit();
|
||||||
|
|
||||||
|
XdgSurfaceInterface *q;
|
||||||
|
XdgShellInterface *shell;
|
||||||
|
QPointer<XdgToplevelInterface> toplevel;
|
||||||
|
QPointer<XdgPopupInterface> popup;
|
||||||
|
QPointer<SurfaceInterface> surface;
|
||||||
|
bool isConfigured = false;
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
QRect windowGeometry;
|
||||||
};
|
};
|
||||||
|
|
||||||
QVector<quint32> configureSerials;
|
State next;
|
||||||
QPointer<SurfaceInterface> parent;
|
State current;
|
||||||
QSize initialSize;
|
|
||||||
|
|
||||||
/*
|
static XdgSurfaceInterfacePrivate *get(XdgSurfaceInterface *surface);
|
||||||
*
|
|
||||||
*/
|
|
||||||
QRect anchorRect;
|
|
||||||
Qt::Edges anchorEdge;
|
|
||||||
Qt::Edges gravity;
|
|
||||||
PositionerConstraints constraintAdjustments;
|
|
||||||
QPoint anchorOffset;
|
|
||||||
|
|
||||||
XdgShellInterfaceVersion interfaceVersion;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Private(XdgShellInterfaceVersion interfaceVersion, XdgShellPopupInterface *q, XdgShellInterface *c, SurfaceInterface *surface, wl_resource *parentResource, const wl_interface *interface, const void *implementation);
|
void xdg_surface_destroy_resource(Resource *resource) override;
|
||||||
|
void xdg_surface_destroy(Resource *resource) override;
|
||||||
|
void xdg_surface_get_toplevel(Resource *resource, uint32_t id) override;
|
||||||
|
void xdg_surface_get_popup(Resource *resource, uint32_t id, ::wl_resource *parent, ::wl_resource *positioner) override;
|
||||||
|
void xdg_surface_set_window_geometry(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) override;
|
||||||
|
void xdg_surface_ack_configure(Resource *resource, uint32_t serial) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
class XdgToplevelInterfacePrivate : public SurfaceRole, public QtWaylandServer::xdg_toplevel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XdgToplevelInterfacePrivate(XdgToplevelInterface *toplevel, XdgSurfaceInterface *surface);
|
||||||
|
|
||||||
#endif
|
void commit() override;
|
||||||
|
|
||||||
|
static XdgToplevelInterfacePrivate *get(XdgToplevelInterface *toplevel);
|
||||||
|
static XdgToplevelInterfacePrivate *get(::wl_resource *resource);
|
||||||
|
|
||||||
|
XdgToplevelInterface *q;
|
||||||
|
QPointer<XdgToplevelInterface> parentXdgToplevel;
|
||||||
|
QPointer<XdgToplevelDecorationV1Interface> decoration;
|
||||||
|
XdgSurfaceInterface *xdgSurface;
|
||||||
|
|
||||||
|
QString windowTitle;
|
||||||
|
QString windowClass;
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
QSize minimumSize;
|
||||||
|
QSize maximumSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
State next;
|
||||||
|
State current;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void xdg_toplevel_destroy_resource(Resource *resource) override;
|
||||||
|
void xdg_toplevel_destroy(Resource *resource) override;
|
||||||
|
void xdg_toplevel_set_parent(Resource *resource, ::wl_resource *parent) override;
|
||||||
|
void xdg_toplevel_set_title(Resource *resource, const QString &title) override;
|
||||||
|
void xdg_toplevel_set_app_id(Resource *resource, const QString &app_id) override;
|
||||||
|
void xdg_toplevel_show_window_menu(Resource *resource, ::wl_resource *seat, uint32_t serial, int32_t x, int32_t y) override;
|
||||||
|
void xdg_toplevel_move(Resource *resource, ::wl_resource *seat, uint32_t serial) override;
|
||||||
|
void xdg_toplevel_resize(Resource *resource, ::wl_resource *seat, uint32_t serial, uint32_t edges) override;
|
||||||
|
void xdg_toplevel_set_max_size(Resource *resource, int32_t width, int32_t height) override;
|
||||||
|
void xdg_toplevel_set_min_size(Resource *resource, int32_t width, int32_t height) override;
|
||||||
|
void xdg_toplevel_set_maximized(Resource *resource) override;
|
||||||
|
void xdg_toplevel_unset_maximized(Resource *resource) override;
|
||||||
|
void xdg_toplevel_set_fullscreen(Resource *resource, ::wl_resource *output) override;
|
||||||
|
void xdg_toplevel_unset_fullscreen(Resource *resource) override;
|
||||||
|
void xdg_toplevel_set_minimized(Resource *resource) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class XdgPopupInterfacePrivate : public SurfaceRole, public QtWaylandServer::xdg_popup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XdgPopupInterfacePrivate(XdgPopupInterface *popup, XdgSurfaceInterface *surface);
|
||||||
|
|
||||||
|
void commit() override;
|
||||||
|
|
||||||
|
XdgPopupInterface *q;
|
||||||
|
XdgSurfaceInterface *parentXdgSurface;
|
||||||
|
XdgSurfaceInterface *xdgSurface;
|
||||||
|
XdgPositioner positioner;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void xdg_popup_destroy_resource(Resource *resource) override;
|
||||||
|
void xdg_popup_destroy(Resource *resource) override;
|
||||||
|
void xdg_popup_grab(Resource *resource, ::wl_resource *seat, uint32_t serial) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KWaylandServer
|
||||||
|
|
Loading…
Reference in a new issue