Skip to content

Commit

Permalink
Add listeners for decoration and toplevel destruction
Browse files Browse the repository at this point in the history
  • Loading branch information
tarek-y-ismail committed Jun 26, 2024
1 parent b8f0b2c commit 0741868
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions src/server/frontend_wayland/xdg_decoration_unstable_v1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "xdg_output_v1.h"
#include "xdg_shell_stable.h"

#include <memory>
#include <unordered_set>

namespace mir
Expand All @@ -45,7 +46,7 @@ class XdgDecorationManagerV1 : public wayland::XdgDecorationManagerV1

private:
void get_toplevel_decoration(wl_resource* id, wl_resource* toplevel) override;
std::unordered_set<wl_resource*> toplevels_with_decorations;
std::shared_ptr<std::unordered_set<wl_resource*>> toplevels_with_decorations;
};

class XdgToplevelDecorationV1 : public wayland::XdgToplevelDecorationV1
Expand Down Expand Up @@ -84,15 +85,16 @@ void mir::frontend::XdgDecorationManagerV1::Global::bind(wl_resource* new_zxdg_d
}

mir::frontend::XdgDecorationManagerV1::XdgDecorationManagerV1(wl_resource* resource) :
mir::wayland::XdgDecorationManagerV1{resource, Version<1>{}}
mir::wayland::XdgDecorationManagerV1{resource, Version<1>{}},
toplevels_with_decorations(std::make_shared<std::unordered_set<wl_resource*>>())
{
}

void mir::frontend::XdgDecorationManagerV1::get_toplevel_decoration(wl_resource* id, wl_resource* toplevel)
{
using Error = mir::frontend::XdgToplevelDecorationV1::Error;

if (toplevels_with_decorations.contains(toplevel))
if (toplevels_with_decorations->contains(toplevel))
{
BOOST_THROW_EXCEPTION(mir::wayland::ProtocolError(
resource, Error::already_constructed, "Decoration already constructed for this toplevel"));
Expand All @@ -104,9 +106,22 @@ void mir::frontend::XdgDecorationManagerV1::get_toplevel_decoration(wl_resource*
BOOST_THROW_EXCEPTION(std::runtime_error("Invalid toplevel pointer"));
}


new XdgToplevelDecorationV1{id, tl};
toplevels_with_decorations.insert(toplevel);
auto decoration = new XdgToplevelDecorationV1{id, tl};
toplevels_with_decorations->insert(toplevel);

decoration->add_destroy_listener([toplevels_with_decorations = this->toplevels_with_decorations, toplevel]()
{ toplevels_with_decorations->erase(toplevel); });

tl->add_destroy_listener(
[toplevels_with_decorations = this->toplevels_with_decorations, toplevel]()
{
if (toplevels_with_decorations->contains(toplevel))
{
toplevels_with_decorations->erase(toplevel);
BOOST_THROW_EXCEPTION(mir::wayland::ProtocolError(
toplevel, Error::orphaned, "Toplevel destroyed before its attached decoration"));
}
});
}

mir::frontend::XdgToplevelDecorationV1::XdgToplevelDecorationV1(
Expand Down

0 comments on commit 0741868

Please sign in to comment.