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_v2.cpp
|
||||
touch_interface.cpp
|
||||
xdgdecoration_interface.cpp
|
||||
xdgdecoration_v1_interface.cpp
|
||||
xdgforeign_interface.cpp
|
||||
xdgforeign_v2_interface.cpp
|
||||
xdgoutput_interface.cpp
|
||||
xdgshell_interface.cpp
|
||||
xdgshell_stable_interface.cpp
|
||||
)
|
||||
|
||||
ecm_qt_declare_logging_category(SERVER_LIB_SRCS
|
||||
|
@ -199,14 +198,14 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
|||
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
|
||||
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
|
||||
BASENAME xdg-decoration
|
||||
BASENAME xdg-decoration-unstable-v1
|
||||
)
|
||||
|
||||
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
||||
|
@ -387,7 +386,7 @@ set(SERVER_LIB_HEADERS
|
|||
tablet_interface.h
|
||||
textinput_interface.h
|
||||
touch_interface.h
|
||||
xdgdecoration_interface.h
|
||||
xdgdecoration_v1_interface.h
|
||||
xdgforeign_interface.h
|
||||
xdgoutput_interface.h
|
||||
xdgshell_interface.h
|
||||
|
|
|
@ -343,16 +343,13 @@ add_test(NAME kwayland-testXdgForeign COMMAND testXdgForeign)
|
|||
ecm_mark_as_test(testXdgForeign)
|
||||
|
||||
########################################################
|
||||
# Test XdgShellStable
|
||||
# Test XdgShell
|
||||
########################################################
|
||||
set( testXdgShellStable_SRCS
|
||||
test_xdg_shell.cpp
|
||||
test_xdg_shell_stable.cpp
|
||||
)
|
||||
add_executable(testXdgShellStable ${testXdgShellStable_SRCS})
|
||||
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)
|
||||
set(testXdgShell_SRCS test_xdg_shell.cpp)
|
||||
add_executable(testXdgShell ${testXdgShell_SRCS})
|
||||
target_link_libraries( testXdgShell Qt5::Test Qt5::Gui Plasma::KWaylandServer KF5::WaylandClient Wayland::Client)
|
||||
add_test(NAME kwayland-testXdgShell COMMAND testXdgShell)
|
||||
ecm_mark_as_test(testXdgShell)
|
||||
|
||||
########################################################
|
||||
# Test Pointer Constraints
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "../../src/server/display.h"
|
||||
#include "../../src/server/compositor_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
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ private:
|
|||
KWaylandServer::Display *m_display = nullptr;
|
||||
KWaylandServer::CompositorInterface *m_compositorInterface = nullptr;
|
||||
KWaylandServer::XdgShellInterface *m_xdgShellInterface = nullptr;
|
||||
KWaylandServer::XdgDecorationManagerInterface *m_xdgDecorationManagerInterface = nullptr;
|
||||
KWaylandServer::XdgDecorationManagerV1Interface *m_xdgDecorationManagerInterface = nullptr;
|
||||
|
||||
KWayland::Client::ConnectionThread *m_connection = nullptr;
|
||||
KWayland::Client::Compositor *m_compositor = nullptr;
|
||||
|
@ -59,7 +59,7 @@ void TestXdgDecoration::init()
|
|||
using namespace KWayland::Client;
|
||||
|
||||
qRegisterMetaType<XdgDecoration::Mode>();
|
||||
qRegisterMetaType<XdgDecorationInterface::Mode>();
|
||||
qRegisterMetaType<XdgToplevelDecorationV1Interface::Mode>();
|
||||
|
||||
delete m_display;
|
||||
m_display = new Display(this);
|
||||
|
@ -104,16 +104,12 @@ void TestXdgDecoration::init()
|
|||
QVERIFY(compositorSpy.wait());
|
||||
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->create();
|
||||
QVERIFY(m_xdgShellInterface->isValid());
|
||||
m_xdgShellInterface = m_display->createXdgShell(m_display);
|
||||
QVERIFY(xdgShellSpy.wait());
|
||||
m_xdgShell = m_registry->createXdgShell(xdgShellSpy.first().first().value<quint32>(),
|
||||
xdgShellSpy.first().last().value<quint32>(), this);
|
||||
|
||||
m_xdgDecorationManagerInterface = m_display->createXdgDecorationManager(m_xdgShellInterface, m_display);
|
||||
m_xdgDecorationManagerInterface->create();
|
||||
QVERIFY(m_xdgDecorationManagerInterface->isValid());
|
||||
m_xdgDecorationManagerInterface = m_display->createXdgDecorationManagerV1(m_display);
|
||||
|
||||
QVERIFY(xdgDecorationManagerSpy.wait());
|
||||
m_xdgDecorationManager = m_registry->createXdgDecorationManager(xdgDecorationManagerSpy.first().first().value<quint32>(),
|
||||
|
@ -160,13 +156,13 @@ void TestXdgDecoration::testDecoration_data()
|
|||
{
|
||||
using namespace KWayland::Client;
|
||||
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>("setMode");
|
||||
QTest::addColumn<KWaylandServer::XdgDecorationInterface::Mode>("setModeExp");
|
||||
QTest::addColumn<KWaylandServer::XdgToplevelDecorationV1Interface::Mode>("setModeExp");
|
||||
|
||||
const auto serverClient = XdgDecorationInterface::Mode::ClientSide;
|
||||
const auto serverServer = XdgDecorationInterface::Mode::ServerSide;
|
||||
const auto serverClient = XdgToplevelDecorationV1Interface::Mode::Client;
|
||||
const auto serverServer = XdgToplevelDecorationV1Interface::Mode::Server;
|
||||
const auto clientClient = XdgDecoration::Mode::ClientSide;
|
||||
const auto clientServer = XdgDecoration::Mode::ServerSide;
|
||||
|
||||
|
@ -181,15 +177,14 @@ void TestXdgDecoration::testDecoration()
|
|||
using namespace KWayland::Client;
|
||||
using namespace KWaylandServer;
|
||||
|
||||
QFETCH(KWaylandServer::XdgDecorationInterface::Mode, configuredMode);
|
||||
QFETCH(KWaylandServer::XdgToplevelDecorationV1Interface::Mode, configuredMode);
|
||||
QFETCH(KWayland::Client::XdgDecoration::Mode, configuredModeExp);
|
||||
QFETCH(KWayland::Client::XdgDecoration::Mode, setMode);
|
||||
QFETCH(KWaylandServer::XdgDecorationInterface::Mode, setModeExp);
|
||||
|
||||
QFETCH(KWaylandServer::XdgToplevelDecorationV1Interface::Mode, setModeExp);
|
||||
|
||||
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
|
||||
QSignalSpy shellSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
||||
QSignalSpy decorationCreatedSpy(m_xdgDecorationManagerInterface, &XdgDecorationManagerInterface::xdgDecorationInterfaceCreated);
|
||||
QSignalSpy shellSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::toplevelCreated);
|
||||
QSignalSpy decorationCreatedSpy(m_xdgDecorationManagerInterface, &XdgDecorationManagerV1Interface::decorationCreated);
|
||||
|
||||
// create shell surface and deco object
|
||||
QScopedPointer<Surface> surface(m_compositor->createSurface());
|
||||
|
@ -201,20 +196,20 @@ void TestXdgDecoration::testDecoration()
|
|||
QVERIFY(shellSurfaceCreatedSpy.count() || shellSurfaceCreatedSpy.wait());
|
||||
QVERIFY(decorationCreatedSpy.count() || decorationCreatedSpy.wait());
|
||||
|
||||
auto shellSurfaceIface = shellSurfaceCreatedSpy.first().first().value<XdgShellSurfaceInterface*>();
|
||||
auto decorationIface = decorationCreatedSpy.first().first().value<XdgDecorationInterface*>();
|
||||
auto shellSurfaceIface = shellSurfaceCreatedSpy.first().first().value<XdgToplevelInterface *>();
|
||||
auto decorationIface = decorationCreatedSpy.first().first().value<XdgToplevelDecorationV1Interface *>();
|
||||
|
||||
QVERIFY(decorationIface);
|
||||
QVERIFY(shellSurfaceIface);
|
||||
QCOMPARE(decorationIface->surface(), shellSurfaceIface);
|
||||
QCOMPARE(decorationIface->requestedMode(), XdgDecorationInterface::Mode::Undefined);
|
||||
QCOMPARE(decorationIface->toplevel(), shellSurfaceIface);
|
||||
QCOMPARE(decorationIface->preferredMode(), XdgToplevelDecorationV1Interface::Mode::Undefined);
|
||||
|
||||
QSignalSpy clientConfiguredSpy(decoration.data(), &XdgDecoration::modeChanged);
|
||||
QSignalSpy modeRequestedSpy(decorationIface, &XdgDecorationInterface::modeRequested);
|
||||
QSignalSpy modeRequestedSpy(decorationIface, &XdgToplevelDecorationV1Interface::preferredModeChanged);
|
||||
|
||||
//server configuring a client
|
||||
decorationIface->configure(configuredMode);
|
||||
quint32 serial = shellSurfaceIface->configure({});
|
||||
decorationIface->sendConfigure(configuredMode);
|
||||
quint32 serial = shellSurfaceIface->sendConfigure(QSize(0, 0), {});
|
||||
QVERIFY(clientConfiguredSpy.wait());
|
||||
QCOMPARE(clientConfiguredSpy.first().first().value<XdgDecoration::Mode>(), configuredModeExp);
|
||||
|
||||
|
@ -223,13 +218,14 @@ void TestXdgDecoration::testDecoration()
|
|||
//client requesting another mode
|
||||
decoration->setMode(setMode);
|
||||
QVERIFY(modeRequestedSpy.wait());
|
||||
QCOMPARE(modeRequestedSpy.first().first().value<XdgDecorationInterface::Mode>(), setModeExp);
|
||||
QCOMPARE(decorationIface->requestedMode(), setModeExp);
|
||||
QCOMPARE(modeRequestedSpy.first().first().value<XdgToplevelDecorationV1Interface::Mode>(), setModeExp);
|
||||
QCOMPARE(decorationIface->preferredMode(), setModeExp);
|
||||
modeRequestedSpy.clear();
|
||||
|
||||
decoration->unsetMode();
|
||||
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)
|
||||
|
|
|
@ -5,14 +5,86 @@
|
|||
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):
|
||||
m_version(version)
|
||||
{}
|
||||
using namespace KWayland::Client;
|
||||
using namespace KWaylandServer;
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::MouseButton)
|
||||
|
||||
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()
|
||||
{
|
||||
delete m_display;
|
||||
|
@ -34,9 +106,7 @@ void XdgShellTest::init()
|
|||
m_seatInterface->create();
|
||||
m_compositorInterface = m_display->createCompositor(m_display);
|
||||
m_compositorInterface->create();
|
||||
m_xdgShellInterface = m_display->createXdgShell(m_version, m_display);
|
||||
QCOMPARE(m_xdgShellInterface->interfaceVersion(), m_version);
|
||||
m_xdgShellInterface->create();
|
||||
m_xdgShellInterface = m_display->createXdgShell(m_display);
|
||||
|
||||
// setup connection
|
||||
m_connection = new KWayland::Client::ConnectionThread;
|
||||
|
@ -62,11 +132,7 @@ void XdgShellTest::init()
|
|||
QSignalSpy outputAnnouncedSpy(®istry, &Registry::outputAnnounced);
|
||||
QVERIFY(outputAnnouncedSpy.isValid());
|
||||
|
||||
auto shellAnnouncedSignal = m_version == XdgShellInterfaceVersion::UnstableV5 ? &Registry::xdgShellUnstableV5Announced :
|
||||
m_version == XdgShellInterfaceVersion::UnstableV6 ? &Registry::xdgShellUnstableV6Announced :
|
||||
&Registry::xdgShellStableAnnounced;
|
||||
|
||||
QSignalSpy xdgShellAnnouncedSpy(®istry, shellAnnouncedSignal);
|
||||
QSignalSpy xdgShellAnnouncedSpy(®istry, &Registry::xdgShellStableAnnounced);
|
||||
QVERIFY(xdgShellAnnouncedSpy.isValid());
|
||||
registry.setEventQueue(m_queue);
|
||||
registry.create(m_connection);
|
||||
|
@ -92,21 +158,8 @@ void XdgShellTest::init()
|
|||
|
||||
QCOMPARE(xdgShellAnnouncedSpy.count(), 1);
|
||||
|
||||
Registry::Interface iface;
|
||||
switch (m_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,
|
||||
m_xdgShell = registry.createXdgShell(registry.interface(Registry::Interface::XdgShellStable).name,
|
||||
registry.interface(Registry::Interface::XdgShellStable).version,
|
||||
this);
|
||||
QVERIFY(m_xdgShell);
|
||||
QVERIFY(m_xdgShell->isValid());
|
||||
|
@ -152,7 +205,7 @@ void XdgShellTest::testCreateSurface()
|
|||
// first created the signal spies for the server
|
||||
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
|
||||
QVERIFY(surfaceCreatedSpy.isValid());
|
||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::surfaceCreated);
|
||||
QSignalSpy xdgSurfaceCreatedSpy(m_xdgShellInterface, &XdgShellInterface::toplevelCreated);
|
||||
QVERIFY(xdgSurfaceCreatedSpy.isValid());
|
||||
|
||||
// create surface
|
||||
|
@ -167,17 +220,15 @@ void XdgShellTest::testCreateSurface()
|
|||
QVERIFY(!xdgSurface.isNull());
|
||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
||||
// verify base things
|
||||
auto serverXdgSurface = xdgSurfaceCreatedSpy.first().first().value<XdgShellSurfaceInterface*>();
|
||||
QVERIFY(serverXdgSurface);
|
||||
QCOMPARE(serverXdgSurface->isConfigurePending(), false);
|
||||
QCOMPARE(serverXdgSurface->title(), QString());
|
||||
QCOMPARE(serverXdgSurface->windowClass(), QByteArray());
|
||||
QCOMPARE(serverXdgSurface->isTransient(), false);
|
||||
QCOMPARE(serverXdgSurface->transientFor(), QPointer<XdgShellSurfaceInterface>());
|
||||
QCOMPARE(serverXdgSurface->surface(), serverSurface);
|
||||
auto serverToplevel = xdgSurfaceCreatedSpy.first().first().value<XdgToplevelInterface *>();
|
||||
QVERIFY(serverToplevel);
|
||||
QCOMPARE(serverToplevel->windowTitle(), QString());
|
||||
QCOMPARE(serverToplevel->windowClass(), QByteArray());
|
||||
QCOMPARE(serverToplevel->parentXdgToplevel(), nullptr);
|
||||
QCOMPARE(serverToplevel->surface(), serverSurface);
|
||||
|
||||
// now let's destroy it
|
||||
QSignalSpy destroyedSpy(serverXdgSurface, &QObject::destroyed);
|
||||
QSignalSpy destroyedSpy(serverToplevel, &QObject::destroyed);
|
||||
QVERIFY(destroyedSpy.isValid());
|
||||
xdgSurface.reset();
|
||||
QVERIFY(destroyedSpy.wait());
|
||||
|
@ -190,16 +241,16 @@ void XdgShellTest::testTitle()
|
|||
SURFACE
|
||||
|
||||
// should not have a title yet
|
||||
QCOMPARE(serverXdgSurface->title(), QString());
|
||||
QCOMPARE(serverXdgToplevel->windowTitle(), QString());
|
||||
|
||||
// lets' change the title
|
||||
QSignalSpy titleChangedSpy(serverXdgSurface, &XdgShellSurfaceInterface::titleChanged);
|
||||
QSignalSpy titleChangedSpy(serverXdgToplevel, &XdgToplevelInterface::windowTitleChanged);
|
||||
QVERIFY(titleChangedSpy.isValid());
|
||||
xdgSurface->setTitle(QStringLiteral("foo"));
|
||||
QVERIFY(titleChangedSpy.wait());
|
||||
QCOMPARE(titleChangedSpy.count(), 1);
|
||||
QCOMPARE(titleChangedSpy.first().first().toString(), QStringLiteral("foo"));
|
||||
QCOMPARE(serverXdgSurface->title(), QStringLiteral("foo"));
|
||||
QCOMPARE(serverXdgToplevel->windowTitle(), QStringLiteral("foo"));
|
||||
}
|
||||
|
||||
void XdgShellTest::testWindowClass()
|
||||
|
@ -209,16 +260,16 @@ void XdgShellTest::testWindowClass()
|
|||
SURFACE
|
||||
|
||||
// should not have a window class yet
|
||||
QCOMPARE(serverXdgSurface->windowClass(), QByteArray());
|
||||
QCOMPARE(serverXdgToplevel->windowClass(), QByteArray());
|
||||
|
||||
// let's change the window class
|
||||
QSignalSpy windowClassChanged(serverXdgSurface, &XdgShellSurfaceInterface::windowClassChanged);
|
||||
QSignalSpy windowClassChanged(serverXdgToplevel, &XdgToplevelInterface::windowClassChanged);
|
||||
QVERIFY(windowClassChanged.isValid());
|
||||
xdgSurface->setAppId(QByteArrayLiteral("org.kde.xdgsurfacetest"));
|
||||
QVERIFY(windowClassChanged.wait());
|
||||
QCOMPARE(windowClassChanged.count(), 1);
|
||||
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()
|
||||
|
@ -226,18 +277,18 @@ void XdgShellTest::testMaximize()
|
|||
// this test verifies that the maximize/unmaximize calls work
|
||||
SURFACE
|
||||
|
||||
QSignalSpy maximizeRequestedSpy(serverXdgSurface, &XdgShellSurfaceInterface::maximizedChanged);
|
||||
QSignalSpy maximizeRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::maximizeRequested);
|
||||
QVERIFY(maximizeRequestedSpy.isValid());
|
||||
QSignalSpy unmaximizeRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::unmaximizeRequested);
|
||||
QVERIFY(unmaximizeRequestedSpy.isValid());
|
||||
|
||||
xdgSurface->setMaximized(true);
|
||||
QVERIFY(maximizeRequestedSpy.wait());
|
||||
QCOMPARE(maximizeRequestedSpy.count(), 1);
|
||||
QCOMPARE(maximizeRequestedSpy.last().first().toBool(), true);
|
||||
|
||||
xdgSurface->setMaximized(false);
|
||||
QVERIFY(maximizeRequestedSpy.wait());
|
||||
QCOMPARE(maximizeRequestedSpy.count(), 2);
|
||||
QCOMPARE(maximizeRequestedSpy.last().first().toBool(), false);
|
||||
QVERIFY(unmaximizeRequestedSpy.wait());
|
||||
QCOMPARE(unmaximizeRequestedSpy.count(), 1);
|
||||
}
|
||||
|
||||
void XdgShellTest::testMinimize()
|
||||
|
@ -245,7 +296,7 @@ void XdgShellTest::testMinimize()
|
|||
// this test verifies that the minimize request is delivered
|
||||
SURFACE
|
||||
|
||||
QSignalSpy minimizeRequestedSpy(serverXdgSurface, &XdgShellSurfaceInterface::minimizeRequested);
|
||||
QSignalSpy minimizeRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::minimizeRequested);
|
||||
QVERIFY(minimizeRequestedSpy.isValid());
|
||||
|
||||
xdgSurface->requestMinimize();
|
||||
|
@ -257,44 +308,35 @@ void XdgShellTest::testFullscreen()
|
|||
{
|
||||
qRegisterMetaType<OutputInterface*>();
|
||||
// this test verifies going to/from fullscreen
|
||||
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);
|
||||
SURFACE
|
||||
|
||||
QSignalSpy fullscreenSpy(serverXdgSurface, &XdgShellSurfaceInterface::fullscreenChanged);
|
||||
QVERIFY(fullscreenSpy.isValid());
|
||||
QSignalSpy fullscreenRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::fullscreenRequested);
|
||||
QVERIFY(fullscreenRequestedSpy.isValid());
|
||||
QSignalSpy unfullscreenRequestedSpy(serverXdgToplevel, &XdgToplevelInterface::unfullscreenRequested);
|
||||
QVERIFY(fullscreenRequestedSpy.isValid());
|
||||
|
||||
// without an output
|
||||
xdgSurface->setFullscreen(true, nullptr);
|
||||
QVERIFY(fullscreenSpy.wait());
|
||||
QCOMPARE(fullscreenSpy.count(), 1);
|
||||
QCOMPARE(fullscreenSpy.last().at(0).toBool(), true);
|
||||
QVERIFY(!fullscreenSpy.last().at(1).value<OutputInterface*>());
|
||||
QVERIFY(fullscreenRequestedSpy.wait());
|
||||
QCOMPARE(fullscreenRequestedSpy.count(), 1);
|
||||
QVERIFY(!fullscreenRequestedSpy.last().at(0).value<OutputInterface*>());
|
||||
|
||||
// unset
|
||||
xdgSurface->setFullscreen(false);
|
||||
QVERIFY(fullscreenSpy.wait());
|
||||
QCOMPARE(fullscreenSpy.count(), 2);
|
||||
QCOMPARE(fullscreenSpy.last().at(0).toBool(), false);
|
||||
QVERIFY(!fullscreenSpy.last().at(1).value<OutputInterface*>());
|
||||
QVERIFY(unfullscreenRequestedSpy.wait());
|
||||
QCOMPARE(unfullscreenRequestedSpy.count(), 1);
|
||||
|
||||
// with outputs
|
||||
xdgSurface->setFullscreen(true, m_output1);
|
||||
QVERIFY(fullscreenSpy.wait());
|
||||
QCOMPARE(fullscreenSpy.count(), 3);
|
||||
QCOMPARE(fullscreenSpy.last().at(0).toBool(), true);
|
||||
QCOMPARE(fullscreenSpy.last().at(1).value<OutputInterface*>(), m_o1Interface);
|
||||
QVERIFY(fullscreenRequestedSpy.wait());
|
||||
QCOMPARE(fullscreenRequestedSpy.count(), 2);
|
||||
QCOMPARE(fullscreenRequestedSpy.last().at(0).value<OutputInterface*>(), m_o1Interface);
|
||||
|
||||
// now other output
|
||||
xdgSurface->setFullscreen(true, m_output2);
|
||||
QVERIFY(fullscreenSpy.wait());
|
||||
QCOMPARE(fullscreenSpy.count(), 4);
|
||||
QCOMPARE(fullscreenSpy.last().at(0).toBool(), true);
|
||||
QCOMPARE(fullscreenSpy.last().at(1).value<OutputInterface*>(), m_o2Interface);
|
||||
QVERIFY(fullscreenRequestedSpy.wait());
|
||||
QCOMPARE(fullscreenRequestedSpy.count(), 3);
|
||||
QCOMPARE(fullscreenRequestedSpy.last().at(0).value<OutputInterface*>(), m_o2Interface);
|
||||
}
|
||||
|
||||
void XdgShellTest::testShowWindowMenu()
|
||||
|
@ -303,7 +345,10 @@ void XdgShellTest::testShowWindowMenu()
|
|||
// this test verifies that the show window menu request works
|
||||
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());
|
||||
|
||||
// TODO: the serial needs to be a proper one
|
||||
|
@ -311,8 +356,8 @@ void XdgShellTest::testShowWindowMenu()
|
|||
QVERIFY(windowMenuSpy.wait());
|
||||
QCOMPARE(windowMenuSpy.count(), 1);
|
||||
QCOMPARE(windowMenuSpy.first().at(0).value<SeatInterface*>(), m_seatInterface);
|
||||
QCOMPARE(windowMenuSpy.first().at(1).value<quint32>(), 20u);
|
||||
QCOMPARE(windowMenuSpy.first().at(2).toPoint(), QPoint(30, 40));
|
||||
QCOMPARE(windowMenuSpy.first().at(1).toPoint(), QPoint(30, 40));
|
||||
QCOMPARE(windowMenuSpy.first().at(2).value<quint32>(), 20u);
|
||||
}
|
||||
|
||||
void XdgShellTest::testMove()
|
||||
|
@ -321,7 +366,10 @@ void XdgShellTest::testMove()
|
|||
// this test verifies that the move request works
|
||||
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());
|
||||
|
||||
// TODO: the serial needs to be a proper one
|
||||
|
@ -353,7 +401,10 @@ void XdgShellTest::testResize()
|
|||
// this test verifies that the resize request works
|
||||
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());
|
||||
|
||||
// TODO: the serial needs to be a proper one
|
||||
|
@ -362,8 +413,8 @@ void XdgShellTest::testResize()
|
|||
QVERIFY(resizeSpy.wait());
|
||||
QCOMPARE(resizeSpy.count(), 1);
|
||||
QCOMPARE(resizeSpy.first().at(0).value<SeatInterface*>(), m_seatInterface);
|
||||
QCOMPARE(resizeSpy.first().at(1).value<quint32>(), 60u);
|
||||
QCOMPARE(resizeSpy.first().at(2).value<Qt::Edges>(), edges);
|
||||
QCOMPARE(resizeSpy.first().at(1).value<Qt::Edges>(), edges);
|
||||
QCOMPARE(resizeSpy.first().at(2).value<quint32>(), 60u);
|
||||
}
|
||||
|
||||
void XdgShellTest::testTransient()
|
||||
|
@ -373,30 +424,28 @@ void XdgShellTest::testTransient()
|
|||
QScopedPointer<Surface> surface2(m_compositor->createSurface());
|
||||
QScopedPointer<XdgShellSurface> xdgSurface2(m_xdgShell->createSurface(surface2.data()));
|
||||
QVERIFY(xdgSurfaceCreatedSpy.wait());
|
||||
auto serverXdgSurface2 = xdgSurfaceCreatedSpy.last().first().value<XdgShellSurfaceInterface*>();
|
||||
QVERIFY(serverXdgSurface2);
|
||||
auto serverXdgToplevel2 = xdgSurfaceCreatedSpy.last().first().value<XdgToplevelInterface *>();
|
||||
QVERIFY(serverXdgToplevel2);
|
||||
|
||||
QVERIFY(!serverXdgSurface->isTransient());
|
||||
QVERIFY(!serverXdgSurface2->isTransient());
|
||||
QVERIFY(!serverXdgToplevel->parentXdgToplevel());
|
||||
QVERIFY(!serverXdgToplevel2->parentXdgToplevel());
|
||||
|
||||
// now make xdsgSurface2 a transient for xdgSurface
|
||||
QSignalSpy transientForSpy(serverXdgSurface2, &XdgShellSurfaceInterface::transientForChanged);
|
||||
QSignalSpy transientForSpy(serverXdgToplevel2, &XdgToplevelInterface::parentXdgToplevelChanged);
|
||||
QVERIFY(transientForSpy.isValid());
|
||||
xdgSurface2->setTransientFor(xdgSurface.data());
|
||||
|
||||
QVERIFY(transientForSpy.wait());
|
||||
QCOMPARE(transientForSpy.count(), 1);
|
||||
QVERIFY(serverXdgSurface2->isTransient());
|
||||
QCOMPARE(serverXdgSurface2->transientFor().data(), serverXdgSurface);
|
||||
QVERIFY(!serverXdgSurface->isTransient());
|
||||
QCOMPARE(serverXdgToplevel2->parentXdgToplevel(), serverXdgToplevel);
|
||||
QVERIFY(!serverXdgToplevel->parentXdgToplevel());
|
||||
|
||||
// unset the transient for
|
||||
xdgSurface2->setTransientFor(nullptr);
|
||||
QVERIFY(transientForSpy.wait());
|
||||
QCOMPARE(transientForSpy.count(), 2);
|
||||
QVERIFY(!serverXdgSurface2->isTransient());
|
||||
QVERIFY(serverXdgSurface2->transientFor().isNull());
|
||||
QVERIFY(!serverXdgSurface->isTransient());
|
||||
QVERIFY(!serverXdgToplevel2->parentXdgToplevel());
|
||||
QVERIFY(!serverXdgToplevel->parentXdgToplevel());
|
||||
}
|
||||
|
||||
void XdgShellTest::testPing()
|
||||
|
@ -407,7 +456,7 @@ void XdgShellTest::testPing()
|
|||
QSignalSpy pingSpy(m_xdgShellInterface, &XdgShellInterface::pongReceived);
|
||||
QVERIFY(pingSpy.isValid());
|
||||
|
||||
quint32 serial = m_xdgShellInterface->ping(serverXdgSurface);
|
||||
quint32 serial = m_xdgShellInterface->ping(serverXdgToplevel->xdgSurface());
|
||||
QVERIFY(pingSpy.wait());
|
||||
QCOMPARE(pingSpy.count(), 1);
|
||||
QCOMPARE(pingSpy.takeFirst().at(0).value<quint32>(), serial);
|
||||
|
@ -415,7 +464,7 @@ void XdgShellTest::testPing()
|
|||
// test of a ping failure
|
||||
// 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);
|
||||
m_xdgShellInterface->ping(serverXdgSurface);
|
||||
m_xdgShellInterface->ping(serverXdgToplevel->xdgSurface());
|
||||
QSignalSpy pingDelayedSpy(m_xdgShellInterface, &XdgShellInterface::pingDelayed);
|
||||
QVERIFY(pingDelayedSpy.wait());
|
||||
|
||||
|
@ -431,11 +480,11 @@ void XdgShellTest::testClose()
|
|||
QSignalSpy closeSpy(xdgSurface.data(), &XdgShellSurface::closeRequested);
|
||||
QVERIFY(closeSpy.isValid());
|
||||
|
||||
serverXdgSurface->close();
|
||||
serverXdgToplevel->sendClose();
|
||||
QVERIFY(closeSpy.wait());
|
||||
QCOMPARE(closeSpy.count(), 1);
|
||||
|
||||
QSignalSpy destroyedSpy(serverXdgSurface, &XdgShellSurfaceInterface::destroyed);
|
||||
QSignalSpy destroyedSpy(serverXdgToplevel, &XdgToplevelInterface::destroyed);
|
||||
QVERIFY(destroyedSpy.isValid());
|
||||
xdgSurface.reset();
|
||||
QVERIFY(destroyedSpy.wait());
|
||||
|
@ -443,20 +492,20 @@ void XdgShellTest::testClose()
|
|||
|
||||
void XdgShellTest::testConfigureStates_data()
|
||||
{
|
||||
QTest::addColumn<XdgShellSurfaceInterface::States>("serverStates");
|
||||
QTest::addColumn<XdgToplevelInterface::States>("serverStates");
|
||||
QTest::addColumn<XdgShellSurface::States>("clientStates");
|
||||
|
||||
const auto sa = XdgShellSurfaceInterface::States(XdgShellSurfaceInterface::State::Activated);
|
||||
const auto sm = XdgShellSurfaceInterface::States(XdgShellSurfaceInterface::State::Maximized);
|
||||
const auto sf = XdgShellSurfaceInterface::States(XdgShellSurfaceInterface::State::Fullscreen);
|
||||
const auto sr = XdgShellSurfaceInterface::States(XdgShellSurfaceInterface::State::Resizing);
|
||||
const auto sa = XdgToplevelInterface::States(XdgToplevelInterface::State::Activated);
|
||||
const auto sm = XdgToplevelInterface::States(XdgToplevelInterface::State::Maximized);
|
||||
const auto sf = XdgToplevelInterface::States(XdgToplevelInterface::State::FullScreen);
|
||||
const auto sr = XdgToplevelInterface::States(XdgToplevelInterface::State::Resizing);
|
||||
|
||||
const auto ca = XdgShellSurface::States(XdgShellSurface::State::Activated);
|
||||
const auto cm = XdgShellSurface::States(XdgShellSurface::State::Maximized);
|
||||
const auto cf = XdgShellSurface::States(XdgShellSurface::State::Fullscreen);
|
||||
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("Maximize") << sm << cm;
|
||||
QTest::newRow("Fullscreen") << sf << cf;
|
||||
|
@ -485,15 +534,15 @@ void XdgShellTest::testConfigureStates()
|
|||
QSignalSpy configureSpy(xdgSurface.data(), &XdgShellSurface::configureRequested);
|
||||
QVERIFY(configureSpy.isValid());
|
||||
|
||||
QFETCH(XdgShellSurfaceInterface::States, serverStates);
|
||||
serverXdgSurface->configure(serverStates);
|
||||
QFETCH(XdgToplevelInterface::States, serverStates);
|
||||
serverXdgToplevel->sendConfigure(QSize(0, 0), serverStates);
|
||||
QVERIFY(configureSpy.wait());
|
||||
QCOMPARE(configureSpy.count(), 1);
|
||||
QCOMPARE(configureSpy.first().at(0).toSize(), QSize(0, 0));
|
||||
QTEST(configureSpy.first().at(1).value<XdgShellSurface::States>(), "clientStates");
|
||||
QCOMPARE(configureSpy.first().at(2).value<quint32>(), m_display->serial());
|
||||
|
||||
QSignalSpy ackSpy(serverXdgSurface, &XdgShellSurfaceInterface::configureAcknowledged);
|
||||
QSignalSpy ackSpy(serverXdgToplevel->xdgSurface(), &XdgSurfaceInterface::configureAcknowledged);
|
||||
QVERIFY(ackSpy.isValid());
|
||||
|
||||
xdgSurface->ackConfigure(configureSpy.first().at(2).value<quint32>());
|
||||
|
@ -512,15 +561,15 @@ void XdgShellTest::testConfigureMultipleAcks()
|
|||
QVERIFY(configureSpy.isValid());
|
||||
QSignalSpy sizeChangedSpy(xdgSurface.data(), &XdgShellSurface::sizeChanged);
|
||||
QVERIFY(sizeChangedSpy.isValid());
|
||||
QSignalSpy ackSpy(serverXdgSurface, &XdgShellSurfaceInterface::configureAcknowledged);
|
||||
QSignalSpy ackSpy(serverXdgToplevel->xdgSurface(), &XdgSurfaceInterface::configureAcknowledged);
|
||||
QVERIFY(ackSpy.isValid());
|
||||
|
||||
serverXdgSurface->configure(XdgShellSurfaceInterface::States(), QSize(10, 20));
|
||||
serverXdgToplevel->sendConfigure(QSize(10, 20), XdgToplevelInterface::States());
|
||||
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();
|
||||
QVERIFY(serial1 != serial2);
|
||||
serverXdgSurface->configure(XdgShellSurfaceInterface::States(), QSize(30, 40));
|
||||
serverXdgToplevel->sendConfigure(QSize(30, 40), XdgToplevelInterface::States());
|
||||
const quint32 serial3 = m_display->serial();
|
||||
QVERIFY(serial1 != serial3);
|
||||
QVERIFY(serial2 != serial3);
|
||||
|
@ -544,16 +593,17 @@ void XdgShellTest::testConfigureMultipleAcks()
|
|||
|
||||
xdgSurface->ackConfigure(serial3);
|
||||
QVERIFY(ackSpy.wait());
|
||||
QCOMPARE(ackSpy.count(), 3);
|
||||
QCOMPARE(ackSpy.at(0).first().value<quint32>(), serial1);
|
||||
QCOMPARE(ackSpy.at(1).first().value<quint32>(), serial2);
|
||||
QCOMPARE(ackSpy.at(2).first().value<quint32>(), serial3);
|
||||
QCOMPARE(ackSpy.count(), 1);
|
||||
QCOMPARE(ackSpy.last().first().value<quint32>(), serial3);
|
||||
|
||||
// configure once more with a null size
|
||||
serverXdgSurface->configure(XdgShellSurfaceInterface::States());
|
||||
serverXdgToplevel->sendConfigure(QSize(0, 0), XdgToplevelInterface::States());
|
||||
// should not change size
|
||||
QVERIFY(configureSpy.wait());
|
||||
QCOMPARE(configureSpy.count(), 4);
|
||||
QCOMPARE(sizeChangedSpy.count(), 3);
|
||||
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 "tablet_interface.h"
|
||||
#include "textinput_interface_p.h"
|
||||
#include "xdgdecoration_interface.h"
|
||||
#include "xdgdecoration_v1_interface.h"
|
||||
#include "xdgforeign_interface.h"
|
||||
#include "xdgoutput_interface.h"
|
||||
#include "xdgshell_stable_interface_p.h"
|
||||
#include "xdgshell_interface.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
@ -377,20 +377,11 @@ TextInputManagerInterface *Display::createTextInputManager(const TextInputInterf
|
|||
return t;
|
||||
}
|
||||
|
||||
XdgShellInterface *Display::createXdgShell(const XdgShellInterfaceVersion &version, QObject *parent)
|
||||
XdgShellInterface *Display::createXdgShell(QObject *parent)
|
||||
{
|
||||
XdgShellInterface *x = nullptr;
|
||||
switch (version) {
|
||||
case XdgShellInterfaceVersion::UnstableV5:
|
||||
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;
|
||||
XdgShellInterface *shell = new XdgShellInterface(this, parent);
|
||||
connect(this, &Display::aboutToTerminate, shell, [shell] { delete shell; });
|
||||
return shell;
|
||||
}
|
||||
|
||||
RelativePointerManagerInterface *Display::createRelativePointerManager(const RelativePointerInterfaceVersion &version, QObject *parent)
|
||||
|
@ -483,9 +474,9 @@ XdgOutputManagerInterface *Display::createXdgOutputManager(QObject *parent)
|
|||
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; });
|
||||
return d;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ class AppMenuManagerInterface;
|
|||
class ServerSideDecorationPaletteManagerInterface;
|
||||
class PlasmaVirtualDesktopManagementInterface;
|
||||
class XdgOutputManagerInterface;
|
||||
class XdgDecorationManagerInterface;
|
||||
class XdgDecorationManagerV1Interface;
|
||||
class EglStreamControllerInterface;
|
||||
class KeyStateInterface;
|
||||
class LinuxDmabufUnstableV1Interface;
|
||||
|
@ -210,7 +210,7 @@ public:
|
|||
*
|
||||
* @since 5.25
|
||||
**/
|
||||
XdgShellInterface *createXdgShell(const XdgShellInterfaceVersion &version, QObject *parent = nullptr);
|
||||
XdgShellInterface *createXdgShell(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Creates the RelativePointerManagerInterface in interface @p version
|
||||
|
@ -299,7 +299,7 @@ public:
|
|||
* @return the created manager
|
||||
* @since 5.54
|
||||
*/
|
||||
XdgDecorationManagerInterface *createXdgDecorationManager(XdgShellInterface *shellInterface, QObject *parent = nullptr);
|
||||
XdgDecorationManagerV1Interface *createXdgDecorationManagerV1(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
static SurfaceRole *get(SurfaceInterface *surface);
|
||||
|
||||
private:
|
||||
QPointer<SurfaceInterface> m_surface;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
explicit CompositorWindow(QWidget *parent = nullptr);
|
||||
virtual ~CompositorWindow();
|
||||
|
||||
void surfaceCreated(KWaylandServer::XdgShellSurfaceInterface *surface);
|
||||
void surfaceCreated(KWaylandServer::XdgToplevelInterface *surface);
|
||||
|
||||
void setSeat(const QPointer<KWaylandServer::SeatInterface> &seat);
|
||||
|
||||
|
@ -94,7 +94,7 @@ protected:
|
|||
|
||||
private:
|
||||
void updateFocus();
|
||||
QList<KWaylandServer::XdgShellSurfaceInterface *> m_stackingOrder;
|
||||
QList<KWaylandServer::XdgToplevelInterface *> m_stackingOrder;
|
||||
QPointer<KWaylandServer::SeatInterface> m_seat;
|
||||
};
|
||||
|
||||
|
@ -106,13 +106,13 @@ CompositorWindow::CompositorWindow(QWidget *parent)
|
|||
|
||||
CompositorWindow::~CompositorWindow() = default;
|
||||
|
||||
void CompositorWindow::surfaceCreated(KWaylandServer::XdgShellSurfaceInterface *surface)
|
||||
void CompositorWindow::surfaceCreated(KWaylandServer::XdgToplevelInterface *surface)
|
||||
{
|
||||
using namespace KWaylandServer;
|
||||
surface->configure(XdgShellSurfaceInterface::States());
|
||||
surface->sendConfigure(QSize(), XdgToplevelInterface::States());
|
||||
m_stackingOrder << surface;
|
||||
connect(surface->surface(), &SurfaceInterface::damaged, this, static_cast<void (CompositorWindow::*)()>(&CompositorWindow::update));
|
||||
connect(surface, &XdgShellSurfaceInterface::destroyed, this,
|
||||
connect(surface, &XdgToplevelInterface::destroyed, this,
|
||||
[surface, this] {
|
||||
m_stackingOrder.removeAll(surface);
|
||||
updateFocus();
|
||||
|
@ -129,7 +129,7 @@ void CompositorWindow::updateFocus()
|
|||
return;
|
||||
}
|
||||
auto it = std::find_if(m_stackingOrder.constBegin(), m_stackingOrder.constEnd(),
|
||||
[](XdgShellSurfaceInterface *toplevel) {
|
||||
[](XdgToplevelInterface *toplevel) {
|
||||
return toplevel->surface()->isMapped();
|
||||
}
|
||||
);
|
||||
|
@ -243,8 +243,7 @@ int main(int argc, char **argv)
|
|||
ddm->create();
|
||||
CompositorInterface *compositor = display.createCompositor(&display);
|
||||
compositor->create();
|
||||
XdgShellInterface *shell = display.createXdgShell(XdgShellInterfaceVersion::Stable);
|
||||
shell->create();
|
||||
XdgShellInterface *shell = display.createXdgShell();
|
||||
display.createShm();
|
||||
OutputInterface *output = display.createOutput(&display);
|
||||
output->setPhysicalSize(QSize(269, 202));
|
||||
|
@ -263,7 +262,7 @@ int main(int argc, char **argv)
|
|||
compositorWindow.setMaximumSize(windowSize);
|
||||
compositorWindow.setGeometry(QRect(QPoint(0, 0), windowSize));
|
||||
compositorWindow.show();
|
||||
QObject::connect(shell, &XdgShellInterface::surfaceCreated, &compositorWindow, &CompositorWindow::surfaceCreated);
|
||||
QObject::connect(shell, &XdgShellInterface::toplevelCreated, &compositorWindow, &CompositorWindow::surfaceCreated);
|
||||
|
||||
// start XWayland
|
||||
if (parser.isSet(xwaylandOption)) {
|
||||
|
|
|
@ -77,8 +77,8 @@ int main(int argc, char **argv)
|
|||
display.createShm();
|
||||
CompositorInterface *compositor = display.createCompositor(&display);
|
||||
compositor->create();
|
||||
XdgShellInterface *shell = display.createXdgShell(XdgShellInterfaceVersion::Stable);
|
||||
shell->create();
|
||||
XdgShellInterface *shell = display.createXdgShell();
|
||||
Q_UNUSED(shell)
|
||||
OutputInterface *output = display.createOutput(&display);
|
||||
output->setPhysicalSize(QSize(10, 10));
|
||||
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
|
||||
*/
|
||||
#ifndef KWAYLAND_SERVER_XDGSHELL_INTERFACE_H
|
||||
#define KWAYLAND_SERVER_XDGSHELL_INTERFACE_H
|
||||
|
||||
#include "global.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <QSize>
|
||||
#pragma once
|
||||
|
||||
#include <KWaylandServer/kwaylandserver_export.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedDataPointer>
|
||||
|
||||
struct wl_resource;
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
class Display;
|
||||
class OutputInterface;
|
||||
class SeatInterface;
|
||||
class SurfaceInterface;
|
||||
class XdgShellPopupInterface;
|
||||
class XdgShellSurfaceInterface;
|
||||
template <typename T>
|
||||
class GenericShellSurface;
|
||||
class XdgShellInterfacePrivate;
|
||||
class XdgSurfaceInterfacePrivate;
|
||||
class XdgToplevelInterfacePrivate;
|
||||
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
|
||||
**/
|
||||
enum class XdgShellInterfaceVersion
|
||||
{
|
||||
/**
|
||||
* xdg_shell (unstable v5)
|
||||
**/
|
||||
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 {
|
||||
/**
|
||||
* 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)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* menus.
|
||||
*
|
||||
* @since 5.25
|
||||
**/
|
||||
class KWAYLANDSERVER_EXPORT XdgShellInterface : public Global
|
||||
* XdgShellInterface corresponds to the WaylandInterface \c xdg_wm_base.
|
||||
*
|
||||
* \since 5.20
|
||||
*/
|
||||
class KWAYLANDSERVER_EXPORT XdgShellInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~XdgShellInterface();
|
||||
|
||||
/**
|
||||
* @returns The interface version used by this XdgShellInterface
|
||||
**/
|
||||
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
|
||||
* Constructs an XdgShellInterface object with the given wayland display \a display.
|
||||
*/
|
||||
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:
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
* This signal is emitted when a new XdgPopupInterface object is created.
|
||||
*/
|
||||
void xdgPopupCreated(KWaylandServer::XdgShellPopupInterface *surface);
|
||||
void popupCreated(XdgPopupInterface *popup);
|
||||
|
||||
/*
|
||||
* Emitted in response to a ping request
|
||||
*
|
||||
* @param serial unique identifier for the request
|
||||
* @since 5.39
|
||||
/**
|
||||
* This signal is emitted when the client has responded to a ping event with serial \a serial.
|
||||
*/
|
||||
void pongReceived(quint32 serial);
|
||||
|
||||
/*
|
||||
* Emitted when the application takes more than expected
|
||||
* to answer to a ping, this will always be emitted before
|
||||
* eventuallt pingTimeout gets emitted
|
||||
/**
|
||||
* @todo Drop this signal.
|
||||
*
|
||||
* @param serial unique identifier for the request
|
||||
* @since 5.39
|
||||
*/
|
||||
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
|
||||
* This signal is emitted when the client has not responded to a ping event with serial
|
||||
* \a serial within a reasonable amount of time and the compositor gave up on it.
|
||||
*/
|
||||
void pingTimeout(quint32 serial);
|
||||
|
||||
protected:
|
||||
class Private;
|
||||
explicit XdgShellInterface(Private *d, QObject *parent = nullptr);
|
||||
/**
|
||||
* This signal is emitted when the client has not responded to a ping event with serial
|
||||
* \a serial within a reasonable amount of time.
|
||||
*/
|
||||
void pingDelayed(quint32 serial);
|
||||
|
||||
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
|
||||
**/
|
||||
class KWAYLANDSERVER_EXPORT XdgShellSurfaceInterface : public Resource
|
||||
* XdgSurfaceInterface corresponds to the Wayland interface \c xdg_surface.
|
||||
*
|
||||
* \since 5.20
|
||||
*/
|
||||
class KWAYLANDSERVER_EXPORT XdgSurfaceInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
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
|
||||
**/
|
||||
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.
|
||||
* Returns the XdgToplevelInterface associated with this XdgSurfaceInterface.
|
||||
*
|
||||
* 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
|
||||
* @param size The requested size
|
||||
* @returns The serial of the configure event
|
||||
* @see configureAcknowledged
|
||||
* @see isConfigurePending
|
||||
**/
|
||||
quint32 configure(States states, const QSize &size = QSize(0, 0));
|
||||
* This method will return \c null if no xdg_popup object is associated with this surface.
|
||||
*/
|
||||
XdgPopupInterface *popup() const;
|
||||
|
||||
/**
|
||||
* @returns @c true if there is a not yet acknowledged configure event.
|
||||
* @see configure
|
||||
* @see configureAcknowledged
|
||||
**/
|
||||
bool isConfigurePending() const;
|
||||
* Returns the XdgShellInterface associated with this XdgSurfaceInterface.
|
||||
*/
|
||||
XdgShellInterface *shell() const;
|
||||
|
||||
/**
|
||||
* @return The SurfaceInterface this XdgSurfaceV5Interface got created for.
|
||||
**/
|
||||
* Returns the SurfaceInterface assigned to this XdgSurfaceInterface.
|
||||
*/
|
||||
SurfaceInterface *surface() const;
|
||||
|
||||
/**
|
||||
* @returns The title of this surface.
|
||||
* @see titleChanged
|
||||
**/
|
||||
QString title() const;
|
||||
QByteArray windowClass() const;
|
||||
* Returns \c true if the surface has been configured; otherwise returns \c false.
|
||||
*/
|
||||
bool isConfigured() const;
|
||||
|
||||
/**
|
||||
* @returns Whether this Surface is a transient for another Surface, that is it has a parent.
|
||||
* @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
|
||||
* Returns the window geometry of the XdgSurfaceInterface.
|
||||
*
|
||||
* If invalid, the geometry of the bufer should be used instead
|
||||
* @since 5.59
|
||||
* This method will return an invalid QRect if the window geometry is not set by the client.
|
||||
*/
|
||||
QRect windowGeometry() const;
|
||||
|
||||
/**
|
||||
* @returns The minimum size for the window specified by the client.
|
||||
* @since 5.65
|
||||
* Returns the XdgSurfaceInterface for the specified wayland resource object \a resource.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @returns The maximum size for the window specified by the client.
|
||||
* @since 5.65
|
||||
* Returns the maximum window geometry size of the toplevel surface.
|
||||
*/
|
||||
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:
|
||||
/**
|
||||
* Emitted whenever the title changes.
|
||||
*
|
||||
* @see title
|
||||
**/
|
||||
void titleChanged(const QString&);
|
||||
* 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.
|
||||
*/
|
||||
void initializeRequested();
|
||||
|
||||
/**
|
||||
* Emitted whenever the window class changes.
|
||||
*
|
||||
* @see windowClass
|
||||
**/
|
||||
void windowClassChanged(const QByteArray&);
|
||||
* This signal is emitted when the toplevel's title has been changed.
|
||||
*/
|
||||
void windowTitleChanged(const QString &windowTitle);
|
||||
|
||||
/**
|
||||
* The surface requested a window move.
|
||||
*
|
||||
* @param seat The SeatInterface on which the surface requested the move
|
||||
* @param serial The serial of the implicit mouse grab which triggered the move
|
||||
**/
|
||||
* This signal is emitted when the toplevel's application id has been changed.
|
||||
*/
|
||||
void windowClassChanged(const QString &windowClass);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* The surface requested a window resize.
|
||||
*
|
||||
* @param seat The SeatInterface on which the surface requested the resize
|
||||
* @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, quint32 serial, Qt::Edges edges);
|
||||
void windowMenuRequested(KWaylandServer::SeatInterface *seat, quint32 serial, const QPoint &surfacePos);
|
||||
* 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
|
||||
* in response to which this request has been issued.
|
||||
*/
|
||||
void resizeRequested(KWaylandServer::SeatInterface *seat, Qt::Edges edges, quint32 serial);
|
||||
|
||||
/**
|
||||
* The surface requested a change of maximized state.
|
||||
* @param maximized Whether the window wants to be maximized
|
||||
**/
|
||||
void maximizedChanged(bool maximized);
|
||||
* This signal is emitted when the toplevel surface wants to become maximized.
|
||||
*/
|
||||
void maximizeRequested();
|
||||
|
||||
/**
|
||||
* The surface requested a change of fullscreen state
|
||||
* @param fullscreen Whether the window wants to be fullscreen
|
||||
* @param output An optional output hint on which the window wants to be fullscreen
|
||||
**/
|
||||
void fullscreenChanged(bool fullscreen, KWaylandServer::OutputInterface *output);
|
||||
* This signal is emitted when the toplevel surface wants to become unmaximized.
|
||||
*/
|
||||
void unmaximizeRequested();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
/**
|
||||
* 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
|
||||
* @since 5.39
|
||||
* This signal is emitted when the parent toplevel has changed.
|
||||
*/
|
||||
void maxSizeChanged(const QSize &size);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
void parentXdgToplevelChanged();
|
||||
|
||||
private:
|
||||
Private *d_func() const;
|
||||
friend class GenericShellSurface<XdgShellSurfaceInterface>;
|
||||
QScopedPointer<XdgToplevelInterfacePrivate> d;
|
||||
friend class XdgToplevelInterfacePrivate;
|
||||
};
|
||||
|
||||
/**
|
||||
* The XdgPositioner class provides a collection of rules for the placement of a popup surface.
|
||||
*
|
||||
* @since 5.25
|
||||
**/
|
||||
class KWAYLANDSERVER_EXPORT XdgShellPopupInterface : public Resource
|
||||
* XdgPositioner corresponds to the Wayland interface \c xdg_positioner.
|
||||
*
|
||||
* \since 5.20
|
||||
*/
|
||||
class KWAYLANDSERVER_EXPORT XdgPositioner
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual ~XdgShellPopupInterface();
|
||||
|
||||
/**
|
||||
* @return The SurfaceInterface this XdgShellPopupInterface got created for.
|
||||
**/
|
||||
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
|
||||
* Constructs an incomplete XdgPositioner object.
|
||||
*/
|
||||
quint32 configure(const QRect &rect);
|
||||
|
||||
XdgPositioner();
|
||||
/**
|
||||
* @returns the parent surface.
|
||||
* @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
|
||||
* Constructs a copy of the XdgPositioner object.
|
||||
*/
|
||||
QSize initialSize() const;
|
||||
XdgPositioner(const XdgPositioner &other);
|
||||
/**
|
||||
* Destructs the XdgPositioner object.
|
||||
*/
|
||||
~XdgPositioner();
|
||||
|
||||
/**
|
||||
* The area this popup should be positioned around
|
||||
* @since 5.39
|
||||
* Assigns the value of \a other to this XdgPositioner object.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Which edge of the anchor should the popup be positioned around
|
||||
* @since 5.39
|
||||
* Returns the surface position offset relative to the position of the anchor on the anchor
|
||||
* 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.
|
||||
*
|
||||
* @since 5.39
|
||||
*/
|
||||
QPoint anchorOffset() const;
|
||||
|
||||
/**
|
||||
* Specifies in what direction the popup should be positioned around the anchor
|
||||
* 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
|
||||
* XdgPopupInterface corresponds to the Wayland interface \c xdg_popup.
|
||||
*
|
||||
* @since 5.39
|
||||
* \since 5.20
|
||||
*/
|
||||
class KWAYLANDSERVER_EXPORT XdgPopupInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
//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;
|
||||
public:
|
||||
XdgPopupInterface(XdgSurfaceInterface *surface, XdgSurfaceInterface *parentSurface,
|
||||
const XdgPositioner &positioner, ::wl_resource *resource);
|
||||
/**
|
||||
* Destructs the XdgPopupInterface object.
|
||||
*/
|
||||
~XdgPopupInterface() override;
|
||||
|
||||
XdgShellInterface *shell() const;
|
||||
|
||||
/**
|
||||
* Specifies how the compositor should position the popup if it does not fit in the requested position
|
||||
* @since 5.39
|
||||
* Returns the parent XdgSurfaceInterface.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
PositionerConstraints constraintAdjustments() const;
|
||||
XdgSurfaceInterface *parentXdgSurface() const;
|
||||
|
||||
/**
|
||||
* Dismiss this popup. This indicates to the client that it should destroy this popup.
|
||||
* The Compositor can invoke this method when e.g. the user clicked outside the popup
|
||||
* to dismiss it.
|
||||
**/
|
||||
void popupDone();
|
||||
* Returns the XdgSurfaceInterface associated with the XdgPopupInterface.
|
||||
*/
|
||||
XdgSurfaceInterface *xdgSurface() const;
|
||||
|
||||
/**
|
||||
* @brief windowGeometryChanged
|
||||
* @param windowGeometry the newly changed geometry of the window contents within the buffer
|
||||
* @since 5.59
|
||||
* Returns the SurfaceInterface associated with the XdgPopupInterface.
|
||||
*/
|
||||
QRect windowGeometry()const;
|
||||
SurfaceInterface *surface() const;
|
||||
|
||||
/**
|
||||
* Returns the XdgPositioner assigned to this XdgPopupInterface.
|
||||
*/
|
||||
XdgPositioner positioner() const;
|
||||
|
||||
/**
|
||||
* Returns \c true if the popup has been configured; otherwise returns \c false.
|
||||
*/
|
||||
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:
|
||||
/**
|
||||
* A configure event with @p serial got acknowledged.
|
||||
* Note: XdgV6 only
|
||||
* @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
|
||||
* This signal is emitted when the xdg-popup has commited the initial state and wants to
|
||||
* be configured. After initializing the popup, you must send a configure event.
|
||||
*/
|
||||
void grabRequested(KWaylandServer::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);
|
||||
void initializeRequested();
|
||||
void grabRequested(SeatInterface *seat, quint32 serial);
|
||||
|
||||
private:
|
||||
friend class GenericShellSurface<XdgShellPopupInterface>;
|
||||
|
||||
Private *d_func() const;
|
||||
QScopedPointer<XdgPopupInterfacePrivate> d;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace KWaylandServer
|
||||
|
||||
Q_DECLARE_METATYPE(KWaylandServer::XdgShellSurfaceInterface *)
|
||||
Q_DECLARE_METATYPE(KWaylandServer::XdgShellPopupInterface *)
|
||||
Q_DECLARE_METATYPE(KWaylandServer::XdgShellSurfaceInterface::State)
|
||||
Q_DECLARE_METATYPE(KWaylandServer::XdgShellSurfaceInterface::States)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(KWaylandServer::PositionerConstraints)
|
||||
|
||||
#endif
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(KWaylandServer::XdgToplevelInterface::States)
|
||||
Q_DECLARE_METATYPE(KWaylandServer::XdgToplevelInterface::State)
|
||||
Q_DECLARE_METATYPE(KWaylandServer::XdgToplevelInterface::States)
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
#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
|
||||
{
|
||||
|
||||
class XdgShellInterface::Private : public Global::Private
|
||||
class XdgToplevelDecorationV1Interface;
|
||||
|
||||
class XdgShellInterfacePrivate : public QtWaylandServer::xdg_wm_base
|
||||
{
|
||||
public:
|
||||
XdgShellInterfaceVersion interfaceVersion;
|
||||
XdgShellInterfacePrivate(XdgShellInterface *shell);
|
||||
|
||||
virtual quint32 ping(XdgShellSurfaceInterface * surface) = 0;
|
||||
void setupTimer(quint32 serial);
|
||||
//pingserial/timer correspondence
|
||||
QHash <quint32, QTimer *> pingTimers;
|
||||
void registerXdgSurface(XdgSurfaceInterface *surface);
|
||||
void unregisterXdgSurface(XdgSurfaceInterface *surface);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
Display *display;
|
||||
QMap<quint32, QTimer *> pings;
|
||||
|
||||
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:
|
||||
virtual ~Private();
|
||||
virtual void popupDone() = 0;
|
||||
virtual QRect windowGeometry() const = 0;
|
||||
Qt::Orientations slideConstraintAdjustments;
|
||||
Qt::Orientations flipConstraintAdjustments;
|
||||
Qt::Orientations resizeConstraintAdjustments;
|
||||
Qt::Edges anchorEdges;
|
||||
Qt::Edges gravityEdges;
|
||||
QPoint offset;
|
||||
QSize size;
|
||||
QRect anchorRect;
|
||||
};
|
||||
|
||||
XdgShellPopupInterface *q_func() {
|
||||
return reinterpret_cast<XdgShellPopupInterface *>(q);
|
||||
}
|
||||
class XdgPositionerPrivate : public QtWaylandServer::xdg_positioner
|
||||
{
|
||||
public:
|
||||
XdgPositionerPrivate(::wl_resource *resource);
|
||||
|
||||
virtual quint32 configure(const QRect &rect) {
|
||||
Q_UNUSED(rect)
|
||||
return 0;
|
||||
QSharedDataPointer<XdgPositionerData> data;
|
||||
|
||||
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;
|
||||
QPointer<SurfaceInterface> parent;
|
||||
QSize initialSize;
|
||||
State next;
|
||||
State current;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
QRect anchorRect;
|
||||
Qt::Edges anchorEdge;
|
||||
Qt::Edges gravity;
|
||||
PositionerConstraints constraintAdjustments;
|
||||
QPoint anchorOffset;
|
||||
|
||||
XdgShellInterfaceVersion interfaceVersion;
|
||||
static XdgSurfaceInterfacePrivate *get(XdgSurfaceInterface *surface);
|
||||
|
||||
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