From 1f5c7477ddbb4d4823d195d77e5d5d060bb35742 Mon Sep 17 00:00:00 2001 From: Campbell Jones Date: Sun, 7 Jul 2024 14:44:26 -0400 Subject: [PATCH] LayerSubsurface -> Subsurface --- src/meson.build | 1 + src/surface/layer.cpp | 32 ++-------------------------- src/surface/layer.hpp | 22 ------------------- src/surface/popup.cpp | 16 ++++++++++++++ src/surface/popup.hpp | 1 + src/surface/subsurface.cpp | 43 ++++++++++++++++++++++++++++++++++++++ src/surface/subsurface.hpp | 40 +++++++++++++++++++++++++++++++++++ src/surface/surface.hpp | 1 + src/surface/view.hpp | 1 + src/surface/xdg_view.cpp | 16 ++++++++++++++ src/types.hpp | 2 +- 11 files changed, 122 insertions(+), 53 deletions(-) create mode 100644 src/surface/subsurface.cpp create mode 100644 src/surface/subsurface.hpp diff --git a/src/meson.build b/src/meson.build index 0108b61d7..ca8bf4466 100644 --- a/src/meson.build +++ b/src/meson.build @@ -10,6 +10,7 @@ magpie_sources = [ 'input/seat.cpp', 'surface/layer.cpp', 'surface/popup.cpp', + 'surface/subsurface.cpp', 'surface/view.cpp', 'surface/xdg_view.cpp', 'surface/xwayland_view.cpp', diff --git a/src/surface/layer.cpp b/src/surface/layer.cpp index 671c847ac..cdfaa39a6 100644 --- a/src/surface/layer.cpp +++ b/src/surface/layer.cpp @@ -4,6 +4,7 @@ #include "popup.hpp" #include "server.hpp" #include "surface.hpp" +#include "subsurface.hpp" #include "types.hpp" #include "wlr-wrap-start.hpp" @@ -29,35 +30,6 @@ static magpie_scene_layer_t magpie_layer_from_wlr_layer(const zwlr_layer_shell_v } } -static void subsurface_map_notify(wl_listener* listener, [[maybe_unused]] void* data) { - wlr_log(WLR_DEBUG, "wlr_subsurface.events.map(listener=%p, data=%p)", (void*) listener, data); - - LayerSubsurface& subsurface = magpie_container_of(listener, subsurface, map); - - wlr_surface_send_enter(subsurface.wlr->surface, &subsurface.parent.output.wlr); -} - -static void subsurface_destroy_notify(wl_listener* listener, [[maybe_unused]] void* data) { - wlr_log(WLR_DEBUG, "wlr_subsurface.events.destroy(listener=%p, data=%p)", (void*) listener, data); - - LayerSubsurface& subsurface = magpie_container_of(listener, subsurface, destroy); - - subsurface.parent.subsurfaces.erase(subsurface.shared_from_this()); -} - -LayerSubsurface::LayerSubsurface(Layer& parent, wlr_subsurface& subsurface) noexcept - : listeners(*this), parent(parent), wlr(&subsurface) { - listeners.map.notify = subsurface_map_notify; - wl_signal_add(&subsurface.surface->events.map, &listeners.map); - listeners.destroy.notify = subsurface_destroy_notify; - wl_signal_add(&subsurface.events.destroy, &listeners.destroy); -} - -LayerSubsurface::~LayerSubsurface() noexcept { - wl_list_remove(&listeners.map.link); - wl_list_remove(&listeners.destroy.link); -} - /* Called when the surface is mapped, or ready to display on-screen. */ static void wlr_layer_surface_v1_map_notify(wl_listener* listener, [[maybe_unused]] void* data) { wlr_log(WLR_DEBUG, "wlr_layer_surface_v1.events.map(listener=%p, data=%p)", (void*) listener, data); @@ -141,7 +113,7 @@ static void wlr_layer_surface_v1_new_subsurface_notify(wl_listener* listener, vo Layer& layer = magpie_container_of(listener, layer, new_subsurface); auto& subsurface = *static_cast(data); - layer.subsurfaces.emplace(std::make_shared(layer, subsurface)); + layer.subsurfaces.emplace(std::make_shared(layer, subsurface)); } Layer::Layer(Output& output, wlr_layer_surface_v1& surface) noexcept diff --git a/src/surface/layer.hpp b/src/surface/layer.hpp index bbde4d611..382fb69d6 100644 --- a/src/surface/layer.hpp +++ b/src/surface/layer.hpp @@ -37,8 +37,6 @@ class Layer final : public Surface { wlr_scene_layer_surface_v1* scene_surface; magpie_scene_layer_t scene_layer = MAGPIE_SCENE_LAYER_NORMAL; - std::set> subsurfaces; - Layer(Output& output, wlr_layer_surface_v1& surface) noexcept; ~Layer() noexcept override; @@ -47,24 +45,4 @@ class Layer final : public Surface { [[nodiscard]] bool is_view() const override; }; -class LayerSubsurface final : public std::enable_shared_from_this { - public: - struct Listeners { - std::reference_wrapper parent; - wl_listener map = {}; - wl_listener destroy = {}; - explicit Listeners(LayerSubsurface& parent) noexcept : parent(parent) {} - }; - - private: - Listeners listeners; - - public: - Layer& parent; - wlr_subsurface* wlr; - - LayerSubsurface(Layer& parent, wlr_subsurface& subsurface) noexcept; - ~LayerSubsurface() noexcept; -}; - #endif diff --git a/src/surface/popup.cpp b/src/surface/popup.cpp index 561294fca..e5f39996d 100644 --- a/src/surface/popup.cpp +++ b/src/surface/popup.cpp @@ -2,6 +2,7 @@ #include "output.hpp" #include "server.hpp" +#include "subsurface.hpp" #include "surface.hpp" #include "types.hpp" @@ -53,6 +54,18 @@ static void popup_new_popup_notify(wl_listener* listener, void* data) { popup.popups.emplace(std::make_shared(popup, *static_cast(data))); } +static void popup_new_subsurface_notify(wl_listener* listener, void* data) { + wlr_log(WLR_DEBUG, "wlr_xdg_popup.events.new_subsurface(listener=%p, data=%p)", (void*) listener, data); + + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_xdg_popup.events.new_subsurface"); + return; + } + + Popup& popup = magpie_container_of(listener, popup, new_subsurface); + popup.subsurfaces.emplace(std::make_shared(popup, *static_cast(data))); +} + Popup::Popup(Surface& parent, wlr_xdg_popup& wlr) noexcept : listeners(*this), server(parent.get_server()), parent(parent), wlr(&wlr) { auto* scene_tree = wlr_scene_xdg_surface_create(wlr_scene_tree_from_node(parent.scene_node), wlr.base); @@ -67,12 +80,15 @@ Popup::Popup(Surface& parent, wlr_xdg_popup& wlr) noexcept wl_signal_add(&wlr.base->events.destroy, &listeners.destroy); listeners.new_popup.notify = popup_new_popup_notify; wl_signal_add(&wlr.base->events.new_popup, &listeners.new_popup); + listeners.new_subsurface.notify = popup_new_subsurface_notify; + wl_signal_add(&wlr.base->surface->events.new_subsurface, &listeners.new_subsurface); } Popup::~Popup() noexcept { wl_list_remove(&listeners.map.link); wl_list_remove(&listeners.destroy.link); wl_list_remove(&listeners.new_popup.link); + wl_list_remove(&listeners.new_subsurface.link); if (wlr != nullptr) { wlr_xdg_popup_destroy(wlr); } diff --git a/src/surface/popup.hpp b/src/surface/popup.hpp index 14f512f6d..f2d241575 100644 --- a/src/surface/popup.hpp +++ b/src/surface/popup.hpp @@ -18,6 +18,7 @@ class Popup final : public Surface { wl_listener map = {}; wl_listener destroy = {}; wl_listener new_popup = {}; + wl_listener new_subsurface = {}; explicit Listeners(Popup& parent) noexcept : parent(parent) {} }; diff --git a/src/surface/subsurface.cpp b/src/surface/subsurface.cpp new file mode 100644 index 000000000..e49fd2c26 --- /dev/null +++ b/src/surface/subsurface.cpp @@ -0,0 +1,43 @@ +#include "subsurface.hpp" + +#include "types.hpp" + +#include + +#include "wlr-wrap-start.hpp" +#include +#include +#include +#include +#include "wlr-wrap-end.hpp" + +static void subsurface_destroy_notify(wl_listener* listener, [[maybe_unused]] void* data) { + wlr_log(WLR_DEBUG, "wlr_subsurface.events.destroy(listener=%p, data=%p)", (void*) listener, data); + + Subsurface& subsurface = magpie_container_of(listener, subsurface, destroy); + + subsurface.parent.subsurfaces.erase(std::dynamic_pointer_cast(subsurface.shared_from_this())); +} + +Subsurface::Subsurface(Surface& parent, wlr_subsurface& subsurface) noexcept + : listeners(*this), parent(parent), wlr(subsurface) { + listeners.destroy.notify = subsurface_destroy_notify; + wl_signal_add(&subsurface.events.destroy, &listeners.destroy); +} + +Subsurface::~Subsurface() noexcept { + wl_list_remove(&listeners.map.link); + wl_list_remove(&listeners.destroy.link); +} + +wlr_surface* Subsurface::get_wlr_surface() const { + return wlr.surface; +} + +Server& Subsurface::get_server() const { + return parent.get_server(); +} + +bool Subsurface::is_view() const { + return false; +} diff --git a/src/surface/subsurface.hpp b/src/surface/subsurface.hpp new file mode 100644 index 000000000..222efe8d8 --- /dev/null +++ b/src/surface/subsurface.hpp @@ -0,0 +1,40 @@ +#ifndef MAGPIE_SUBSURFACE_HPP +#define MAGPIE_SUBSURFACE_HPP + +#include "server.hpp" +#include "surface.hpp" +#include "types.hpp" + +#include +#include +#include + +#include "wlr-wrap-start.hpp" +#include +#include "wlr-wrap-end.hpp" + +class Subsurface final : public Surface { + public: + struct Listeners { + std::reference_wrapper parent; + wl_listener map = {}; + wl_listener destroy = {}; + explicit Listeners(Subsurface& parent) noexcept : parent(parent) {} + }; + + private: + Listeners listeners; + + public: + Surface& parent; + wlr_subsurface& wlr; + + Subsurface(Surface& parent, wlr_subsurface& subsurface) noexcept; + ~Subsurface() noexcept override; + + [[nodiscard]] wlr_surface* get_wlr_surface() const override; + [[nodiscard]] Server& get_server() const override; + [[nodiscard]] bool is_view() const override; +}; + +#endif diff --git a/src/surface/surface.hpp b/src/surface/surface.hpp index e777ae193..7e5775130 100644 --- a/src/surface/surface.hpp +++ b/src/surface/surface.hpp @@ -13,6 +13,7 @@ struct Surface : public virtual std::enable_shared_from_this { wlr_scene_node* scene_node = nullptr; std::set> popups; + std::set> subsurfaces; virtual ~Surface() noexcept = default; diff --git a/src/surface/view.hpp b/src/surface/view.hpp index 2580d6ac2..26de9daa7 100644 --- a/src/surface/view.hpp +++ b/src/surface/view.hpp @@ -80,6 +80,7 @@ class XdgView final : public View { wl_listener set_app_id = {}; wl_listener set_parent = {}; wl_listener new_popup = {}; + wl_listener new_subsurface = {}; explicit Listeners(XdgView& parent) noexcept : parent(parent) {} }; diff --git a/src/surface/xdg_view.cpp b/src/surface/xdg_view.cpp index 1eb6f55f3..30b149f7f 100644 --- a/src/surface/xdg_view.cpp +++ b/src/surface/xdg_view.cpp @@ -4,6 +4,7 @@ #include "output.hpp" #include "popup.hpp" #include "server.hpp" +#include "subsurface.hpp" #include "surface.hpp" #include "input/seat.hpp" @@ -147,6 +148,18 @@ static void xdg_surface_new_popup_notify(wl_listener* listener, void* data) { view.popups.emplace(std::make_shared(view, *static_cast(data))); } +static void xdg_surface_new_subsurface_notify(wl_listener* listener, void* data) { + wlr_log(WLR_DEBUG, "wlr_xdg_toplevel.events.new_subsurface(listener=%p, data=%p)", (void*) listener, data); + + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_xdg_surface.events.new_subsurface"); + return; + } + + XdgView& view = magpie_container_of(listener, view, new_subsurface); + view.subsurfaces.emplace(std::make_shared(view, *static_cast(data))); +} + XdgView::XdgView(Server& server, wlr_xdg_toplevel& xdg_toplevel) noexcept : listeners(*this), server(server), wlr(xdg_toplevel) { auto* scene_tree = wlr_scene_xdg_surface_create(&server.scene->tree, xdg_toplevel.base); @@ -194,6 +207,8 @@ XdgView::XdgView(Server& server, wlr_xdg_toplevel& xdg_toplevel) noexcept wl_signal_add(&wlr.events.set_parent, &listeners.set_parent); listeners.new_popup.notify = xdg_surface_new_popup_notify; wl_signal_add(&wlr.base->events.new_popup, &listeners.new_popup); + listeners.new_subsurface.notify = xdg_surface_new_subsurface_notify; + wl_signal_add(&wlr.base->surface->events.new_subsurface, &listeners.new_subsurface); } XdgView::~XdgView() noexcept { @@ -208,6 +223,7 @@ XdgView::~XdgView() noexcept { wl_list_remove(&listeners.set_app_id.link); wl_list_remove(&listeners.set_parent.link); wl_list_remove(&listeners.new_popup.link); + wl_list_remove(&listeners.new_subsurface.link); } wlr_surface* XdgView::get_wlr_surface() const { diff --git a/src/types.hpp b/src/types.hpp index 0c871ee5e..aaef110af 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -15,7 +15,7 @@ struct View; class XdgView; class XWaylandView; class Layer; -class LayerSubsurface; +class Subsurface; class Popup; class ForeignToplevelHandle;