diff --git a/src/server/frontend_wayland/layer_shell_v1.cpp b/src/server/frontend_wayland/layer_shell_v1.cpp index cf52e1e7ea2..c7dac5ed0bb 100644 --- a/src/server/frontend_wayland/layer_shell_v1.cpp +++ b/src/server/frontend_wayland/layer_shell_v1.cpp @@ -21,8 +21,11 @@ #include "wl_surface.h" #include "window_wl_surface_role.h" #include "xdg_shell_stable.h" +#include "wayland_utils.h" #include "mir/shell/surface_specification.h" +#include "mir/frontend/session.h" +#include "mir/log.h" #include #include #include @@ -89,6 +92,8 @@ class LayerSurfaceV1 : public wayland::LayerSurfaceV1, public WindowWlSurfaceRol ~LayerSurfaceV1() = default; + static auto from(wl_resource* surface) -> std::experimental::optional; + private: struct OptionalSize { @@ -158,6 +163,29 @@ mf::LayerShellV1::LayerShellV1( { } +auto mf::LayerShellV1::get_window(wl_resource* surface) -> std::shared_ptr +{ + namespace mw = mir::wayland; + + if (mw::LayerSurfaceV1::is_instance(surface)) + { + auto const layer_surface = LayerSurfaceV1::from(surface); + if (layer_surface) + { + auto const id = layer_surface.value()->surface_id(); + if (id.as_value()) + { + auto const session = get_session(static_cast(layer_surface.value())->client); + return session->get_surface(id); + } + } + + log_debug("No window currently associated with wayland::LayerSurfaceV1 %p", surface); + } + + return {}; +} + void mf::LayerShellV1::bind(wl_resource* new_resource) { new Instance{new_resource, this}; @@ -202,6 +230,18 @@ mf::LayerSurfaceV1::LayerSurfaceV1( apply_spec(spec); } +auto mf::LayerSurfaceV1::from(wl_resource* surface) -> std::experimental::optional +{ + if (!mw::LayerSurfaceV1::is_instance(surface)) + return std::experimental::nullopt; + auto const mw_surface = mw::LayerSurfaceV1::from(surface); + auto const mf_surface = dynamic_cast(mw_surface); + if (mf_surface) + return mf_surface; + else + return std::experimental::nullopt; +} + auto mf::LayerSurfaceV1::get_placement_gravity() const -> MirPlacementGravity { MirPlacementGravity edges = mir_placement_gravity_center; diff --git a/src/server/frontend_wayland/layer_shell_v1.h b/src/server/frontend_wayland/layer_shell_v1.h index 2230b1e844a..59bbcf0fe30 100644 --- a/src/server/frontend_wayland/layer_shell_v1.h +++ b/src/server/frontend_wayland/layer_shell_v1.h @@ -27,6 +27,7 @@ namespace frontend { class Shell; +class Surface; class WlSeat; class OutputManager; @@ -34,6 +35,7 @@ class LayerShellV1 : public wayland::LayerShellV1::Global { public: LayerShellV1(wl_display* display, std::shared_ptr const shell, WlSeat& seat, OutputManager* output_manager); + static auto get_window(wl_resource* surface) -> std::shared_ptr; std::shared_ptr const shell; WlSeat& seat; diff --git a/src/server/frontend_wayland/wayland_default_configuration.cpp b/src/server/frontend_wayland/wayland_default_configuration.cpp index 1246de67162..f826a72259c 100644 --- a/src/server/frontend_wayland/wayland_default_configuration.cpp +++ b/src/server/frontend_wayland/wayland_default_configuration.cpp @@ -203,5 +203,8 @@ auto mir::frontend::get_window(wl_resource* surface) -> std::shared_ptr if (auto result = XdgShellV6::get_window(surface)) return result; + if (auto result = LayerShellV1::get_window(surface)) + return result; + return {}; }