summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2024-06-08 12:03:47 +0200
committerVaxry <vaxry@vaxry.net>2024-06-08 12:03:47 +0200
commit211353dc34b8f0fa17fc1e4d1d5f04d6fe1910e5 (patch)
treed0665d48481c62450c0c97da3bfaea95670885f4 /src
parent10e02076b183f508ef72198366d53902fe0d9098 (diff)
core: verify surface roles on creation of objects
Diffstat (limited to 'src')
-rw-r--r--src/protocols/LayerShell.cpp22
-rw-r--r--src/protocols/LayerShell.hpp10
-rw-r--r--src/protocols/XDGShell.cpp22
-rw-r--r--src/protocols/XDGShell.hpp5
-rw-r--r--src/protocols/core/Subcompositor.cpp5
5 files changed, 55 insertions, 9 deletions
diff --git a/src/protocols/LayerShell.cpp b/src/protocols/LayerShell.cpp
index 8fa6dd27..d4b105cb 100644
--- a/src/protocols/LayerShell.cpp
+++ b/src/protocols/LayerShell.cpp
@@ -159,6 +159,12 @@ CLayerShellResource::CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<C
CLayerShellResource::~CLayerShellResource() {
events.destroy.emit();
+ if (surface)
+ surface->resetRole();
+}
+
+eSurfaceRole CLayerShellResource::role() {
+ return SURFACE_ROLE_LAYER_SHELL;
}
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_) {
const auto CLIENT = pMgr->client();
const auto PMONITOR = output ? CWLOutputResource::fromResource(output)->monitor.get() : nullptr;
- const auto RESOURCE = m_vLayers.emplace_back(
- makeShared<CLayerShellResource>(makeShared<CZwlrLayerSurfaceV1>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surface), namespace_, PMONITOR, layer));
+ auto SURF = CWLSurfaceResource::fromResource(surface);
+
+ 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()) {
pMgr->noMemory();
@@ -216,6 +233,7 @@ void CLayerShellProtocol::onGetLayerSurface(CZwlrLayerShellV1* pMgr, uint32_t id
return;
}
+ SURF->role = RESOURCE;
g_pCompositor->m_vLayers.emplace_back(CLayerSurface::create(RESOURCE));
LOGM(LOG, "New wlr_layer_surface {:x}", (uintptr_t)RESOURCE.get());
diff --git a/src/protocols/LayerShell.hpp b/src/protocols/LayerShell.hpp
index f348e86b..7fa14447 100644
--- a/src/protocols/LayerShell.hpp
+++ b/src/protocols/LayerShell.hpp
@@ -8,18 +8,20 @@
#include "wlr-layer-shell-unstable-v1.hpp"
#include "../helpers/Vector2D.hpp"
#include "../helpers/signal/Signal.hpp"
+#include "types/SurfaceRole.hpp"
class CMonitor;
class CWLSurfaceResource;
-class CLayerShellResource {
+class CLayerShellResource : public ISurfaceRole {
public:
CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<CWLSurfaceResource> surf_, std::string namespace_, CMonitor* pMonitor, zwlrLayerShellV1Layer layer);
~CLayerShellResource();
- bool good();
- void configure(const Vector2D& size);
- void sendClosed();
+ bool good();
+ void configure(const Vector2D& size);
+ void sendClosed();
+ virtual eSurfaceRole role();
enum eCommittedState {
STATE_SIZE = (1 << 0),
diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp
index 191a1124..dcbc6162 100644
--- a/src/protocols/XDGShell.cpp
+++ b/src/protocols/XDGShell.cpp
@@ -419,6 +419,12 @@ CXDGSurfaceResource::~CXDGSurfaceResource() {
events.destroy.emit();
if (configureSource)
wl_event_source_remove(configureSource);
+ if (surface)
+ surface->resetRole();
+}
+
+eSurfaceRole CXDGSurfaceResource::role() {
+ return SURFACE_ROLE_XDG_SHELL;
}
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) {
- const auto RESOURCE = PROTO::xdgShell->m_vSurfaces.emplace_back(
- makeShared<CXDGSurfaceResource>(makeShared<CXdgSurface>(r->client(), r->version(), id), self.lock(), CWLSurfaceResource::fromResource(surf)));
+ auto SURF = 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()) {
r->noMemory();
@@ -656,6 +673,7 @@ CXDGWMBase::CXDGWMBase(SP<CXdgWmBase> resource_) : resource(resource_) {
}
RESOURCE->self = RESOURCE;
+ SURF->role = RESOURCE;
surfaces.emplace_back(RESOURCE);
diff --git a/src/protocols/XDGShell.hpp b/src/protocols/XDGShell.hpp
index fe2517a2..d60db86a 100644
--- a/src/protocols/XDGShell.hpp
+++ b/src/protocols/XDGShell.hpp
@@ -9,6 +9,7 @@
#include "../helpers/Vector2D.hpp"
#include "../helpers/Box.hpp"
#include "../helpers/signal/Signal.hpp"
+#include "types/SurfaceRole.hpp"
class CXDGWMBase;
class CXDGPositionerResource;
@@ -137,13 +138,15 @@ class CXDGToplevelResource {
void applyState();
};
-class CXDGSurfaceResource {
+class CXDGSurfaceResource : public ISurfaceRole {
public:
CXDGSurfaceResource(SP<CXdgSurface> resource_, SP<CXDGWMBase> owner_, SP<CWLSurfaceResource> surface_);
~CXDGSurfaceResource();
static SP<CXDGSurfaceResource> fromResource(wl_resource*);
+ virtual eSurfaceRole role();
+
bool good();
WP<CXDGWMBase> owner;
diff --git a/src/protocols/core/Subcompositor.cpp b/src/protocols/core/Subcompositor.cpp
index 213fdc42..d407636c 100644
--- a/src/protocols/core/Subcompositor.cpp
+++ b/src/protocols/core/Subcompositor.cpp
@@ -133,6 +133,11 @@ CWLSubcompositorResource::CWLSubcompositorResource(SP<CWlSubcompositor> resource
return;
}
+ if (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) {
+ r->error(-1, "Surface already has a different role");
+ return;
+ }
+
SP<CWLSurfaceResource> t1Parent = nullptr;
if (PARENT->role->role() == SURFACE_ROLE_SUBSURFACE) {