core: verify surface roles on creation of objects

This commit is contained in:
Vaxry 2024-06-08 12:03:47 +02:00
parent 10e02076b1
commit 211353dc34
5 changed files with 55 additions and 9 deletions

View file

@ -159,6 +159,12 @@ CLayerShellResource::CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<C
CLayerShellResource::~CLayerShellResource() { CLayerShellResource::~CLayerShellResource() {
events.destroy.emit(); events.destroy.emit();
if (surface)
surface->resetRole();
}
eSurfaceRole CLayerShellResource::role() {
return SURFACE_ROLE_LAYER_SHELL;
} }
bool CLayerShellResource::good() { bool CLayerShellResource::good() {
@ -207,8 +213,19 @@ void CLayerShellProtocol::destroyResource(CLayerShellResource* surf) {
void CLayerShellProtocol::onGetLayerSurface(CZwlrLayerShellV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* output, zwlrLayerShellV1Layer layer, std::string namespace_) { void CLayerShellProtocol::onGetLayerSurface(CZwlrLayerShellV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* output, zwlrLayerShellV1Layer layer, std::string namespace_) {
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
const auto PMONITOR = output ? CWLOutputResource::fromResource(output)->monitor.get() : nullptr; const auto PMONITOR = output ? CWLOutputResource::fromResource(output)->monitor.get() : nullptr;
const auto RESOURCE = m_vLayers.emplace_back( auto SURF = CWLSurfaceResource::fromResource(surface);
makeShared<CLayerShellResource>(makeShared<CZwlrLayerSurfaceV1>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surface), namespace_, PMONITOR, layer));
if (!SURF) {
pMgr->error(-1, "Invalid surface");
return;
}
if (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) {
pMgr->error(-1, "Surface already has a different role");
return;
}
const auto RESOURCE = m_vLayers.emplace_back(makeShared<CLayerShellResource>(makeShared<CZwlrLayerSurfaceV1>(CLIENT, pMgr->version(), id), SURF, namespace_, PMONITOR, layer));
if (!RESOURCE->good()) { if (!RESOURCE->good()) {
pMgr->noMemory(); pMgr->noMemory();
@ -216,6 +233,7 @@ void CLayerShellProtocol::onGetLayerSurface(CZwlrLayerShellV1* pMgr, uint32_t id
return; return;
} }
SURF->role = RESOURCE;
g_pCompositor->m_vLayers.emplace_back(CLayerSurface::create(RESOURCE)); g_pCompositor->m_vLayers.emplace_back(CLayerSurface::create(RESOURCE));
LOGM(LOG, "New wlr_layer_surface {:x}", (uintptr_t)RESOURCE.get()); LOGM(LOG, "New wlr_layer_surface {:x}", (uintptr_t)RESOURCE.get());

View file

@ -8,11 +8,12 @@
#include "wlr-layer-shell-unstable-v1.hpp" #include "wlr-layer-shell-unstable-v1.hpp"
#include "../helpers/Vector2D.hpp" #include "../helpers/Vector2D.hpp"
#include "../helpers/signal/Signal.hpp" #include "../helpers/signal/Signal.hpp"
#include "types/SurfaceRole.hpp"
class CMonitor; class CMonitor;
class CWLSurfaceResource; class CWLSurfaceResource;
class CLayerShellResource { class CLayerShellResource : public ISurfaceRole {
public: public:
CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<CWLSurfaceResource> surf_, std::string namespace_, CMonitor* pMonitor, zwlrLayerShellV1Layer layer); CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<CWLSurfaceResource> surf_, std::string namespace_, CMonitor* pMonitor, zwlrLayerShellV1Layer layer);
~CLayerShellResource(); ~CLayerShellResource();
@ -20,6 +21,7 @@ class CLayerShellResource {
bool good(); bool good();
void configure(const Vector2D& size); void configure(const Vector2D& size);
void sendClosed(); void sendClosed();
virtual eSurfaceRole role();
enum eCommittedState { enum eCommittedState {
STATE_SIZE = (1 << 0), STATE_SIZE = (1 << 0),

View file

@ -419,6 +419,12 @@ CXDGSurfaceResource::~CXDGSurfaceResource() {
events.destroy.emit(); events.destroy.emit();
if (configureSource) if (configureSource)
wl_event_source_remove(configureSource); wl_event_source_remove(configureSource);
if (surface)
surface->resetRole();
}
eSurfaceRole CXDGSurfaceResource::role() {
return SURFACE_ROLE_XDG_SHELL;
} }
bool CXDGSurfaceResource::good() { bool CXDGSurfaceResource::good() {
@ -646,8 +652,19 @@ CXDGWMBase::CXDGWMBase(SP<CXdgWmBase> resource_) : resource(resource_) {
}); });
resource->setGetXdgSurface([this](CXdgWmBase* r, uint32_t id, wl_resource* surf) { resource->setGetXdgSurface([this](CXdgWmBase* r, uint32_t id, wl_resource* surf) {
const auto RESOURCE = PROTO::xdgShell->m_vSurfaces.emplace_back( auto SURF = CWLSurfaceResource::fromResource(surf);
makeShared<CXDGSurfaceResource>(makeShared<CXdgSurface>(r->client(), r->version(), id), self.lock(), CWLSurfaceResource::fromResource(surf)));
if (!SURF) {
r->error(-1, "Invalid surface passed");
return;
}
if (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) {
r->error(-1, "Surface already has a different role");
return;
}
const auto RESOURCE = PROTO::xdgShell->m_vSurfaces.emplace_back(makeShared<CXDGSurfaceResource>(makeShared<CXdgSurface>(r->client(), r->version(), id), self.lock(), SURF));
if (!RESOURCE->good()) { if (!RESOURCE->good()) {
r->noMemory(); r->noMemory();
@ -656,6 +673,7 @@ CXDGWMBase::CXDGWMBase(SP<CXdgWmBase> resource_) : resource(resource_) {
} }
RESOURCE->self = RESOURCE; RESOURCE->self = RESOURCE;
SURF->role = RESOURCE;
surfaces.emplace_back(RESOURCE); surfaces.emplace_back(RESOURCE);

View file

@ -9,6 +9,7 @@
#include "../helpers/Vector2D.hpp" #include "../helpers/Vector2D.hpp"
#include "../helpers/Box.hpp" #include "../helpers/Box.hpp"
#include "../helpers/signal/Signal.hpp" #include "../helpers/signal/Signal.hpp"
#include "types/SurfaceRole.hpp"
class CXDGWMBase; class CXDGWMBase;
class CXDGPositionerResource; class CXDGPositionerResource;
@ -137,13 +138,15 @@ class CXDGToplevelResource {
void applyState(); void applyState();
}; };
class CXDGSurfaceResource { class CXDGSurfaceResource : public ISurfaceRole {
public: public:
CXDGSurfaceResource(SP<CXdgSurface> resource_, SP<CXDGWMBase> owner_, SP<CWLSurfaceResource> surface_); CXDGSurfaceResource(SP<CXdgSurface> resource_, SP<CXDGWMBase> owner_, SP<CWLSurfaceResource> surface_);
~CXDGSurfaceResource(); ~CXDGSurfaceResource();
static SP<CXDGSurfaceResource> fromResource(wl_resource*); static SP<CXDGSurfaceResource> fromResource(wl_resource*);
virtual eSurfaceRole role();
bool good(); bool good();
WP<CXDGWMBase> owner; WP<CXDGWMBase> owner;

View file

@ -133,6 +133,11 @@ CWLSubcompositorResource::CWLSubcompositorResource(SP<CWlSubcompositor> resource
return; return;
} }
if (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) {
r->error(-1, "Surface already has a different role");
return;
}
SP<CWLSurfaceResource> t1Parent = nullptr; SP<CWLSurfaceResource> t1Parent = nullptr;
if (PARENT->role->role() == SURFACE_ROLE_SUBSURFACE) { if (PARENT->role->role() == SURFACE_ROLE_SUBSURFACE) {