Skip to content

Commit

Permalink
wlr-surface-controller: handle subsurface reordering
Browse files Browse the repository at this point in the history
Fixes #1272
  • Loading branch information
ammen99 committed Mar 27, 2024
1 parent 8364a65 commit 292bcdc
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/api/wayfire/unstable/wlr-subsurface-controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class wlr_subsurface_root_node_t : public wf::scene::translation_node_t
public:
wlr_subsurface_root_node_t(wlr_subsurface *subsurface);
std::string stringify() const override;
void update_offset();
bool update_offset(bool damage = true);

private:
wlr_subsurface *subsurface;
Expand Down
2 changes: 2 additions & 0 deletions src/api/wayfire/unstable/wlr-surface-controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class wlr_surface_controller_t
wlr_surface_controller_t(wlr_surface *surface, scene::floating_inner_ptr root_node);
~wlr_surface_controller_t();

void update_subsurface_order_and_position();

scene::floating_inner_ptr root;
wlr_surface *surface;

Expand Down
4 changes: 0 additions & 4 deletions src/view/view-impl.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "wayfire/core.hpp"
#include "../core/core-impl.hpp"
#include "view-impl.hpp"
#include "wayfire/scene-input.hpp"
#include "wayfire/scene-render.hpp"
Expand All @@ -8,15 +7,12 @@
#include "wayfire/unstable/wlr-surface-controller.hpp"
#include "wayfire/unstable/wlr-surface-node.hpp"
#include "wayfire/view.hpp"
#include "wayfire/workspace-set.hpp"
#include "wayfire/output-layout.hpp"
#include <memory>
#include <wayfire/util/log.hpp>
#include <wayfire/view-helpers.hpp>
#include <wayfire/scene-operations.hpp>

#include "xdg-shell.hpp"

void wf::view_implementation::emit_view_map_signal(wayfire_view view, bool has_position)
{
wf::view_mapped_signal data;
Expand Down
15 changes: 9 additions & 6 deletions src/view/wlr-subsurface-controller.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
#include "view/view-impl.hpp"
#include "wayfire/geometry.hpp"
#include "wayfire/scene-operations.hpp"
#include "wayfire/scene.hpp"
#include "wayfire/signal-definitions.hpp"
#include "wayfire/unstable/translation-node.hpp"
#include "wayfire/unstable/wlr-subsurface-controller.hpp"
#include "wayfire/unstable/wlr-surface-node.hpp"
#include <memory>
#include <wayfire/debug.hpp>
#include <cassert>

wf::wlr_subsurface_controller_t::wlr_subsurface_controller_t(wlr_subsurface *sub)
{
Expand Down Expand Up @@ -81,13 +77,20 @@ std::string wf::wlr_subsurface_root_node_t::stringify() const
return "subsurface root node";
}

void wf::wlr_subsurface_root_node_t::update_offset()
bool wf::wlr_subsurface_root_node_t::update_offset(bool apply_damage)
{
wf::point_t offset = {subsurface->current.x, subsurface->current.y};
if (offset != get_offset())
const bool changed = offset != get_offset();

if (changed && apply_damage)
{
scene::damage_node(this, get_bounding_box());
set_offset(offset);
scene::damage_node(this, get_bounding_box());
} else if (changed)
{
set_offset(offset);
}

return changed;
}
102 changes: 88 additions & 14 deletions src/view/wlr-surface-controller.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
#include <algorithm>
#include <map>
#include <wayfire/util/log.hpp>
#include "wayfire/geometry.hpp"
#include "wayfire/opengl.hpp"
#include "../core/core-impl.hpp"
#include "wayfire/output.hpp"
#include <wayfire/util/log.hpp>
#include "wayfire/render-manager.hpp"
#include "wayfire/scene-render.hpp"
#include "wayfire/scene.hpp"
#include "wayfire/signal-definitions.hpp"
#include "wayfire/unstable/wlr-surface-controller.hpp"
#include "wayfire/unstable/wlr-surface-node.hpp"
#include "wayfire/unstable/wlr-subsurface-controller.hpp"
#include <wayfire/scene-operations.hpp>

Expand All @@ -20,7 +13,8 @@ static void update_subsurface_position(wlr_surface *surface, int, int, void*)
{
if (sub->data)
{
((wf::wlr_subsurface_controller_t*)sub->data)->get_subsurface_root()->update_offset();
auto sub_root = ((wf::wlr_subsurface_controller_t*)sub->data)->get_subsurface_root();
sub_root->update_offset();
}
}
}
Expand Down Expand Up @@ -72,15 +66,17 @@ wf::wlr_surface_controller_t::wlr_surface_controller_t(wlr_surface *surface,
on_new_subsurface.emit(sub);
}

if (!wlr_subsurface_try_from_wlr_surface(surface))
on_commit.set_callback([=] (void*)
{
on_commit.set_callback([=] (void*)
if (!wlr_subsurface_try_from_wlr_surface(surface))
{
wlr_surface_for_each_surface(surface, update_subsurface_position, nullptr);
});
}

on_commit.connect(&surface->events.commit);
}
update_subsurface_order_and_position();
});

on_commit.connect(&surface->events.commit);
}

wf::wlr_surface_controller_t::~wlr_surface_controller_t()
Expand All @@ -101,3 +97,81 @@ void wf::wlr_surface_controller_t::try_free_controller(wlr_surface *surface)
delete (wlr_surface_controller_t*)surface->data;
}
}

void wf::wlr_surface_controller_t::update_subsurface_order_and_position()
{
auto old_bbox = root->get_bounding_box();

// Calculate whether we need to reorder the surfaces.
auto all_subsurfaces = this->root->get_children();

// Go until we find the main node, it should be a wlr_surface node.
auto it = std::find_if(all_subsurfaces.begin(), all_subsurfaces.end(),
[=] (const scene::node_ptr& node)
{
if (auto wlr_node = dynamic_cast<scene::wlr_surface_node_t*>(node.get()))
{
return wlr_node->get_surface() == surface;
}

return false;
});

if (it == all_subsurfaces.end())
{
// Maybe unmapped? Can't do anything at the moment anyway.
return;
}

// Now, put all subsurfaces above in the right order, then main view, then subsurfaces below.
// For nodes that we have not copied, we put them at the start/end depending on their original
// position.
std::vector<scene::node_ptr> new_subsurface_order;

// Update subsurface order
bool subsurface_repositioned = false;

wlr_subsurface *sub;
wl_list_for_each_reverse(sub, &surface->current.subsurfaces_above, current.link)
{
auto sub_root = ((wf::wlr_subsurface_controller_t*)sub->data)->get_subsurface_root();
new_subsurface_order.push_back(sub_root);
subsurface_repositioned |= sub_root->update_offset(false);
}
new_subsurface_order.push_back(*it);
wl_list_for_each_reverse(sub, &surface->current.subsurfaces_below, current.link)
{
auto sub_root = ((wf::wlr_subsurface_controller_t*)sub->data)->get_subsurface_root();
new_subsurface_order.push_back(sub_root);
subsurface_repositioned |= sub_root->update_offset(false);
}

// Place compositor subsurfaces correctly: either on top or below.
for (auto iter = all_subsurfaces.begin(); iter != all_subsurfaces.end(); ++iter)
{
if (!dynamic_cast<scene::wlr_surface_node_t*>(iter->get()) &&
!dynamic_cast<wlr_subsurface_root_node_t*>(iter->get()))
{
if (iter < it)
{
new_subsurface_order.insert(new_subsurface_order.begin(), *iter);
} else
{
new_subsurface_order.push_back(*iter);
}
}
}

const bool order_changed = new_subsurface_order != all_subsurfaces;
if (order_changed || subsurface_repositioned)
{
wf::scene::damage_node(root, old_bbox);
if (order_changed)
{
root->set_children_list(new_subsurface_order);
wf::scene::update(root, wf::scene::update_flag::CHILDREN_LIST);
}

wf::scene::damage_node(root, root->get_bounding_box());
}
}

0 comments on commit 292bcdc

Please sign in to comment.