diff --git a/src/decorations/ssd.cpp b/src/decorations/ssd.cpp index 2e211cf7d..e413a2f54 100644 --- a/src/decorations/ssd.cpp +++ b/src/decorations/ssd.cpp @@ -22,6 +22,7 @@ Ssd::Ssd(View& parent) noexcept : view(parent) { auto titlebar_color = rrggbb_to_floats(TITLEBAR_COLOR); auto view_geo = view.get_surface_geometry(); titlebar_rect = wlr_scene_rect_create(scene_tree, view_geo.width, TITLEBAR_HEIGHT, titlebar_color.data()); + titlebar_rect->node.data = &parent; wlr_scene_node_set_position(&titlebar_rect->node, BORDER_WIDTH, BORDER_WIDTH); wlr_scene_node_lower_to_bottom(&titlebar_rect->node); wlr_scene_node_set_enabled(&titlebar_rect->node, true); diff --git a/src/input/cursor.cpp b/src/input/cursor.cpp index 050541279..83076d4b5 100644 --- a/src/input/cursor.cpp +++ b/src/input/cursor.cpp @@ -436,14 +436,15 @@ void Cursor::process_motion(const uint32_t time) { double sy; wlr_surface* surface = nullptr; auto magpie_surface = seat.server.surface_at(wlr.x, wlr.y, &surface, &sx, &sy).lock(); - if (magpie_surface == nullptr) { + bool ssd_at_cursor = seat.server.ssd_at(wlr.x, wlr.y); + if (ssd_at_cursor || magpie_surface == nullptr) { /* If there's no view under the cursor, set the cursor image to a * default. This is what makes the cursor image appear when you move it * around the screen, not over any views. */ set_image("left_ptr"); } - if (surface != nullptr) { + if (!ssd_at_cursor && surface != nullptr) { /* * Send pointer enter and motion events. * diff --git a/src/server.cpp b/src/server.cpp index 73070bcb6..41931ac2e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -133,21 +133,45 @@ void Server::focus_layer(std::shared_ptr layer) { } } +bool Server::ssd_at(const double lx, const double ly) const { + double sx; + double sy; + wlr_scene_node* node = wlr_scene_node_at(&scene->tree.node, lx, ly, &sx, &sy); + if (node == nullptr) { + return false; + } + + if (node->type == WLR_SCENE_NODE_RECT && node->data != nullptr) { + return true; + } + + return false; +} + std::weak_ptr Server::surface_at(const double lx, const double ly, wlr_surface** wlr, double* sx, double* sy) const { /* This returns the topmost node in the scene at the given layout coords. * we only care about surface nodes as we are specifically looking for a * surface in the surface tree of a magpie_view. */ wlr_scene_node* node = wlr_scene_node_at(&scene->tree.node, lx, ly, sx, sy); - if (node == nullptr || node->type != WLR_SCENE_NODE_BUFFER) { + if (node == nullptr) { return {}; } - wlr_scene_buffer* scene_buffer = wlr_scene_buffer_from_node(node); - const wlr_scene_surface* scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer); - if (scene_surface == nullptr) { + + if (node->type == WLR_SCENE_NODE_RECT && node->data != nullptr) { + auto* view = static_cast(node->data); + *wlr = view->get_wlr_surface(); + } else if (node->type == WLR_SCENE_NODE_BUFFER) { + wlr_scene_buffer* scene_buffer = wlr_scene_buffer_from_node(node); + const wlr_scene_surface* scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer); + if (scene_surface == nullptr) { + return {}; + } + + *wlr = scene_surface->surface; + } else { return {}; } - *wlr = scene_surface->surface; /* Find the node corresponding to the magpie_view at the root of this * surface tree, it is the only one for which we set the data field. */ const wlr_scene_tree* tree = node->parent; diff --git a/src/server.hpp b/src/server.hpp index ed9935a2b..003ae0bb1 100644 --- a/src/server.hpp +++ b/src/server.hpp @@ -29,6 +29,7 @@ #include #include #include "wlr-wrap-end.hpp" +#include "decorations/ssd.hpp" using magpie_scene_layer_t = enum magpie_scene_layer { MAGPIE_SCENE_LAYER_BACKGROUND = 0, @@ -111,6 +112,7 @@ class Server final : public std::enable_shared_from_this { Server(); std::weak_ptr surface_at(double lx, double ly, wlr_surface** wlr, double* sx, double* sy) const; + bool ssd_at(double lx, double ly) const; void focus_view(std::shared_ptr&& view); void focus_layer(std::shared_ptr layer); void try_focus_next_exclusive_layer(); diff --git a/src/surface/xdg_view.cpp b/src/surface/xdg_view.cpp index 53af4d9b3..d58d42266 100644 --- a/src/surface/xdg_view.cpp +++ b/src/surface/xdg_view.cpp @@ -190,6 +190,7 @@ static void xdg_surface_new_subsurface_notify(wl_listener* listener, void* data) XdgView::XdgView(Server& server, wlr_xdg_toplevel& xdg_toplevel) noexcept : listeners(*this), server(server), wlr(xdg_toplevel) { scene_tree = wlr_scene_tree_create(&server.scene->tree); + scene_tree->node.data = this; auto* surface_tree = wlr_scene_xdg_surface_create(scene_tree, xdg_toplevel.base); surface_node = &surface_tree->node;