From addd3e7f1aeb670dd91d26005aaeccce3efb1ae7 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Sat, 25 May 2024 22:43:51 +0200 Subject: xwayland: move to hyprland impl (#6086) --- src/protocols/XDGOutput.cpp | 3 +- src/protocols/XWaylandShell.cpp | 84 ++++++++++++++++++++++++++++++++++++++ src/protocols/XWaylandShell.hpp | 66 ++++++++++++++++++++++++++++++ src/protocols/types/DataDevice.cpp | 4 ++ src/protocols/types/DataDevice.hpp | 6 +++ 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 src/protocols/XWaylandShell.cpp create mode 100644 src/protocols/XWaylandShell.hpp (limited to 'src/protocols') diff --git a/src/protocols/XDGOutput.cpp b/src/protocols/XDGOutput.cpp index 9d3e2ac9..771f5f78 100644 --- a/src/protocols/XDGOutput.cpp +++ b/src/protocols/XDGOutput.cpp @@ -1,6 +1,7 @@ #include "XDGOutput.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +#include "../xwayland/XWayland.hpp" #define OUTPUT_MANAGER_VERSION 3 #define OUTPUT_DONE_DEPRECATED_SINCE_VERSION 3 @@ -55,7 +56,7 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(CZxdgOutputManagerV1* mgr, uint32 CXDGOutput* pXDGOutput = m_vXDGOutputs.emplace_back(std::make_unique(makeShared(CLIENT, mgr->version(), id), PMONITOR)).get(); #ifndef NO_XWAYLAND - if (g_pXWaylandManager->m_sWLRXWayland && g_pXWaylandManager->m_sWLRXWayland->server && g_pXWaylandManager->m_sWLRXWayland->server->client == CLIENT) + if (g_pXWayland && g_pXWayland->pServer && g_pXWayland->pServer->xwaylandClient == CLIENT) pXDGOutput->isXWayland = true; #endif pXDGOutput->client = CLIENT; diff --git a/src/protocols/XWaylandShell.cpp b/src/protocols/XWaylandShell.cpp new file mode 100644 index 00000000..8b9905f8 --- /dev/null +++ b/src/protocols/XWaylandShell.cpp @@ -0,0 +1,84 @@ +#include "XWaylandShell.hpp" +#include + +#define LOGM PROTO::xwaylandShell->protoLog + +CXWaylandSurfaceResource::CXWaylandSurfaceResource(SP resource_, wlr_surface* surface_) : surface(surface_), resource(resource_) { + if (!good()) + return; + + resource->setDestroy([this](CXwaylandSurfaceV1* r) { + events.destroy.emit(); + PROTO::xwaylandShell->destroyResource(this); + }); + resource->setOnDestroy([this](CXwaylandSurfaceV1* r) { + events.destroy.emit(); + PROTO::xwaylandShell->destroyResource(this); + }); + + pClient = resource->client(); + + resource->setSetSerial([this](CXwaylandSurfaceV1* r, uint32_t lo, uint32_t hi) { + serial = (((uint64_t)hi) << 32) + lo; + PROTO::xwaylandShell->events.newSurface.emit(self.lock()); + }); +} + +CXWaylandSurfaceResource::~CXWaylandSurfaceResource() { + events.destroy.emit(); +} + +bool CXWaylandSurfaceResource::good() { + return resource->resource(); +} + +wl_client* CXWaylandSurfaceResource::client() { + return pClient; +} + +CXWaylandShellResource::CXWaylandShellResource(SP resource_) : resource(resource_) { + if (!good()) + return; + + resource->setDestroy([this](CXwaylandShellV1* r) { PROTO::xwaylandShell->destroyResource(this); }); + resource->setOnDestroy([this](CXwaylandShellV1* r) { PROTO::xwaylandShell->destroyResource(this); }); + + resource->setGetXwaylandSurface([this](CXwaylandShellV1* r, uint32_t id, wl_resource* surface) { + const auto RESOURCE = PROTO::xwaylandShell->m_vSurfaces.emplace_back( + makeShared(makeShared(r->client(), r->version(), id), wlr_surface_from_resource(surface))); + + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::xwaylandShell->m_vSurfaces.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + }); +} + +bool CXWaylandShellResource::good() { + return resource->resource(); +} + +CXWaylandShellProtocol::CXWaylandShellProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CXWaylandShellProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); + + if (!RESOURCE->good()) { + wl_client_post_no_memory(client); + m_vManagers.pop_back(); + return; + } +} + +void CXWaylandShellProtocol::destroyResource(CXWaylandShellResource* resource) { + std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; }); +} + +void CXWaylandShellProtocol::destroyResource(CXWaylandSurfaceResource* resource) { + std::erase_if(m_vSurfaces, [&](const auto& other) { return other.get() == resource; }); +} diff --git a/src/protocols/XWaylandShell.hpp b/src/protocols/XWaylandShell.hpp new file mode 100644 index 00000000..2c03d172 --- /dev/null +++ b/src/protocols/XWaylandShell.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include +#include "WaylandProtocol.hpp" +#include "xwayland-shell-v1.hpp" +#include "../helpers/signal/Signal.hpp" + +class CXWaylandSurfaceResource { + public: + CXWaylandSurfaceResource(SP resource_, wlr_surface* surface_); + ~CXWaylandSurfaceResource(); + + bool good(); + wl_client* client(); + + struct { + CSignal destroy; + } events; + + uint64_t serial = 0; + wlr_surface* surface = nullptr; + + WP self; + + private: + SP resource; + wl_client* pClient = nullptr; +}; + +class CXWaylandShellResource { + public: + CXWaylandShellResource(SP resource_); + + bool good(); + + private: + SP resource; +}; + +class CXWaylandShellProtocol : public IWaylandProtocol { + public: + CXWaylandShellProtocol(const wl_interface* iface, const int& ver, const std::string& name); + + virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); + + struct { + CSignal newSurface; // SP. Fired when it sets a serial, otherwise it's useless + } events; + + private: + void destroyResource(CXWaylandSurfaceResource* resource); + void destroyResource(CXWaylandShellResource* resource); + + // + std::vector> m_vManagers; + std::vector> m_vSurfaces; + + friend class CXWaylandSurfaceResource; + friend class CXWaylandShellResource; +}; + +namespace PROTO { + inline UP xwaylandShell; +}; diff --git a/src/protocols/types/DataDevice.cpp b/src/protocols/types/DataDevice.cpp index 47cbda8b..eb6969cc 100644 --- a/src/protocols/types/DataDevice.cpp +++ b/src/protocols/types/DataDevice.cpp @@ -15,3 +15,7 @@ bool IDataSource::used() { void IDataSource::markUsed() { wasUsed = true; } + +eDataSourceType IDataSource::type() { + return DATA_SOURCE_TYPE_WAYLAND; +} diff --git a/src/protocols/types/DataDevice.hpp b/src/protocols/types/DataDevice.hpp index 98a97c14..948f47a0 100644 --- a/src/protocols/types/DataDevice.hpp +++ b/src/protocols/types/DataDevice.hpp @@ -5,6 +5,11 @@ #include #include "../../helpers/signal/Signal.hpp" +enum eDataSourceType { + DATA_SOURCE_TYPE_WAYLAND = 0, + DATA_SOURCE_TYPE_X11, +}; + class IDataSource { public: IDataSource() {} @@ -19,6 +24,7 @@ class IDataSource { virtual bool used(); virtual void markUsed(); virtual void error(uint32_t code, const std::string& msg) = 0; + virtual eDataSourceType type(); struct { CSignal destroy; -- cgit v1.2.3