diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2024-05-25 22:43:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-25 22:43:51 +0200 |
| commit | addd3e7f1aeb670dd91d26005aaeccce3efb1ae7 (patch) | |
| tree | 7eae3cf1d780ab84ff34ee0fce5ed85d9ee69c90 /src/protocols | |
| parent | a71207434c0bc2c8e05e94b1619e68059a002879 (diff) | |
xwayland: move to hyprland impl (#6086)
Diffstat (limited to 'src/protocols')
| -rw-r--r-- | src/protocols/XDGOutput.cpp | 3 | ||||
| -rw-r--r-- | src/protocols/XWaylandShell.cpp | 84 | ||||
| -rw-r--r-- | src/protocols/XWaylandShell.hpp | 66 | ||||
| -rw-r--r-- | src/protocols/types/DataDevice.cpp | 4 | ||||
| -rw-r--r-- | src/protocols/types/DataDevice.hpp | 6 |
5 files changed, 162 insertions, 1 deletions
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<CXDGOutput>(makeShared<CZxdgOutputV1>(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 <algorithm> + +#define LOGM PROTO::xwaylandShell->protoLog + +CXWaylandSurfaceResource::CXWaylandSurfaceResource(SP<CXwaylandSurfaceV1> 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<CXwaylandShellV1> 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<CXWaylandSurfaceResource>(makeShared<CXwaylandSurfaceV1>(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<CXWaylandShellResource>(makeShared<CXwaylandShellV1>(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 <memory> +#include <vector> +#include <cstdint> +#include "WaylandProtocol.hpp" +#include "xwayland-shell-v1.hpp" +#include "../helpers/signal/Signal.hpp" + +class CXWaylandSurfaceResource { + public: + CXWaylandSurfaceResource(SP<CXwaylandSurfaceV1> resource_, wlr_surface* surface_); + ~CXWaylandSurfaceResource(); + + bool good(); + wl_client* client(); + + struct { + CSignal destroy; + } events; + + uint64_t serial = 0; + wlr_surface* surface = nullptr; + + WP<CXWaylandSurfaceResource> self; + + private: + SP<CXwaylandSurfaceV1> resource; + wl_client* pClient = nullptr; +}; + +class CXWaylandShellResource { + public: + CXWaylandShellResource(SP<CXwaylandShellV1> resource_); + + bool good(); + + private: + SP<CXwaylandShellV1> 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<CXWaylandSurfaceResource>. Fired when it sets a serial, otherwise it's useless + } events; + + private: + void destroyResource(CXWaylandSurfaceResource* resource); + void destroyResource(CXWaylandShellResource* resource); + + // + std::vector<SP<CXWaylandShellResource>> m_vManagers; + std::vector<SP<CXWaylandSurfaceResource>> m_vSurfaces; + + friend class CXWaylandSurfaceResource; + friend class CXWaylandShellResource; +}; + +namespace PROTO { + inline UP<CXWaylandShellProtocol> 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 <cstdint> #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; |
