Skip to content

Commit

Permalink
tmp: start refactoring view ownership to use shared_ptr
Browse files Browse the repository at this point in the history
  • Loading branch information
ammen99 committed Jul 28, 2023
1 parent c86d2c9 commit 057bfc6
Show file tree
Hide file tree
Showing 26 changed files with 170 additions and 293 deletions.
9 changes: 3 additions & 6 deletions plugins/animate/animate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "wayfire/scene-operations.hpp"
#include "wayfire/scene.hpp"
#include "wayfire/signal-provider.hpp"
#include "wayfire/view.hpp"
#include <wayfire/matcher.hpp>

void animation_base::init(wayfire_view, int, wf_animation_type)
Expand Down Expand Up @@ -67,8 +68,8 @@ struct animation_hook : public animation_hook_base
static_assert(std::is_base_of<animation_base, animation_t>::value,
"animation_type must be derived from animation_base!");

std::shared_ptr<wf::view_interface_t> view;
wf_animation_type type;
wayfire_view view;
std::string name;
wf::output_t *current_output = nullptr;
std::unique_ptr<animation_base> animation;
Expand Down Expand Up @@ -125,7 +126,7 @@ struct animation_hook : public animation_hook_base
std::string name)
{
this->type = type;
this->view = view;
this->view = view->shared_from_this();
this->name = name;

animation = std::make_unique<animation_t>();
Expand All @@ -135,10 +136,7 @@ struct animation_hook : public animation_hook_base
/* Animation is driven by the output render cycle the view is on.
* Thus, we need to keep in sync with the current output. */
view->connect(&on_set_output);

// Take a ref on the view, so that it remains available for as long as the animation runs.
wf::scene::set_node_enabled(view->get_root_node(), true);
view->take_ref();

if (type == ANIMATION_TYPE_UNMAP)
{
Expand Down Expand Up @@ -216,7 +214,6 @@ struct animation_hook : public animation_hook_base

unset_unmapped_contents();
wf::scene::set_node_enabled(view->get_root_node(), false);
view->unref();
}

animation_hook(const animation_hook &) = delete;
Expand Down
17 changes: 8 additions & 9 deletions plugins/single_plugins/move.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "wayfire/debug.hpp"
#include "wayfire/geometry.hpp"
#include "wayfire/plugins/common/input-grab.hpp"
#include "wayfire/nonstd/tracking-allocator.hpp"
#include "wayfire/scene-input.hpp"
#include "wayfire/signal-provider.hpp"
#include "wayfire/view-helpers.hpp"
Expand Down Expand Up @@ -44,7 +45,7 @@ class wayfire_move : public wf::per_output_plugin_instance_t,

struct
{
nonstd::observer_ptr<wf::preview_indication_view_t> preview;
std::shared_ptr<wf::preview_indication_view_t> preview;
wf::grid::slot_t slot_id = wf::grid::SLOT_NONE;
} slot;

Expand Down Expand Up @@ -485,14 +486,12 @@ class wayfire_move : public wf::per_output_plugin_instance_t,
}

auto input = get_input_coords();
auto preview =
new wf::preview_indication_view_t({input.x, input.y, 1, 1}, "move");
wf::get_core().add_view(
std::unique_ptr<wf::view_interface_t>(preview));
preview->set_output(output);

preview->set_target_geometry(slot_geometry, 1);
slot.preview = nonstd::make_observer(preview);
slot.preview = wf::tracking_allocator_t<wf::view_interface_t>::get()
.allocate<wf::preview_indication_view_t>(wf::geometry_t{input.x, input.y, 1, 1}, "move");

wf::view_interface_t::initialize_new(slot.preview);
slot.preview->set_output(output);
slot.preview->set_target_geometry(slot_geometry, 1);
}

update_workspace_switch_timeout(new_slot_id);
Expand Down
10 changes: 5 additions & 5 deletions plugins/tile/tree-controller.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "tree-controller.hpp"

#include <set>
#include <wayfire/nonstd/tracking-allocator.hpp>
#include <algorithm>
#include <wayfire/core.hpp>
#include <wayfire/output.hpp>
Expand Down Expand Up @@ -242,11 +243,10 @@ void move_view_controller_t::ensure_preview(wf::point_t start)
return;
}

auto view =
std::make_unique<wf::preview_indication_view_t>(start, "simple-tile");
this->preview = {view};
wf::get_core().add_view(std::move(view));
this->preview->set_output(output);
preview = wf::tracking_allocator_t<wf::view_interface_t>::get()
.allocate<wf::preview_indication_view_t>(start, "simple-tile");
wf::view_interface_t::initialize_new(preview);
preview->set_output(output);
}

void move_view_controller_t::input_motion(wf::point_t input)
Expand Down
2 changes: 1 addition & 1 deletion plugins/tile/tree-controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class move_view_controller_t : public tile_controller_t
wf::output_t *output;
wf::point_t current_input;

nonstd::observer_ptr<wf::preview_indication_view_t> preview;
std::shared_ptr<wf::preview_indication_view_t> preview;
/**
* Create preview if it doesn't exist
*
Expand Down
11 changes: 3 additions & 8 deletions src/api/wayfire/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,17 +250,12 @@ class compositor_core_t : public wf::object_base_t, public signal::provider_t
nonstd::observer_ptr<wf::touch::gesture_t> gesture) = 0;

/**
* Add a view to the compositor's view list. The view will be freed when
* its keep_count drops to zero, hence a plugin using this doesn't have to
* erase the view manually (instead it should just drop the keep_count)
*/
virtual void add_view(std::unique_ptr<wf::view_interface_t> view) = 0;

/**
* @deprecated. Use tracking_allocator_t<view_interface_t>::get_all()
*
* @return A list of all views core manages, regardless of their output,
* properties, etc.
*/
virtual std::vector<wayfire_view> get_all_views() = 0;
std::vector<wayfire_view> get_all_views();

/**
* Focus the given output. The currently focused output is used to determine
Expand Down
4 changes: 4 additions & 0 deletions src/api/wayfire/nonstd/observer_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ class observer_ptr
nop_constexpr14 observer_ptr(const std::unique_ptr<W2>& other)
: ptr(other.get()) {}

template< class W2 >
nop_constexpr14 observer_ptr(const std::shared_ptr<W2>& other)
: ptr(other.get()) {}

nop_constexpr14 pointer get() const nop_noexcept
{
return ptr;
Expand Down
9 changes: 0 additions & 9 deletions src/api/wayfire/signal-definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,15 +358,6 @@ struct fullscreen_layer_focused_signal
/* ----------------------------------------------------------------------------/
* View signals
* -------------------------------------------------------------------------- */
/**
* on: core
* when: A view is created.
*/
struct view_added_signal
{
wayfire_view view;
};

/**
* on: view, output, core
* when: After the view becomes mapped. This signal must also be emitted from all compositor views.
Expand Down
10 changes: 10 additions & 0 deletions src/api/wayfire/toplevel-view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@ class toplevel_view_interface_t : public wf::view_interface_t

virtual ~toplevel_view_interface_t();

std::shared_ptr<toplevel_view_interface_t> shared_from_this()
{
return std::dynamic_pointer_cast<toplevel_view_interface_t>(view_interface_t::shared_from_this());
}

std::weak_ptr<toplevel_view_interface_t> weak_from_this()
{
return shared_from_this();
}

protected:
/**
* When a view is being destroyed, all associated objects like subsurfaces,
Expand Down
42 changes: 13 additions & 29 deletions src/api/wayfire/view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ namespace scene
class view_node_t;
}

// A signal emitted when the view is destroyed and its memory will be freed.
struct view_destruct_signal
{
wayfire_view view;
};

/* abstraction for desktop-apis, no real need for plugins
* This is a base class to all "drawables" - desktop views, subsurfaces, popups */
enum view_role_t
Expand All @@ -55,10 +49,19 @@ enum view_role_t
};

/**
* view_interface_t is the base class for all "toplevel windows", i.e surfaces
* which have no parent.
* The view_interface_t represents a window shown to the user. It includes panels, backgrounds, notifications,
* and toplevels (which derive from the subclass toplevel_view_interface_t).
*
* Views should be allocated via the helper allocator tracking_allocator_t<view_interface_t>:
* ```
* auto& alloc = tracking_allocator_t<view_interface_t>::get();
* alloc.allocate<concrete view class>(arguments)
* ```
*
* This ensures that all plugins can query a list of all available views at any given time.
*/
class view_interface_t : public wf::signal::provider_t, public wf::object_base_t
class view_interface_t : public wf::signal::provider_t, public wf::object_base_t,
public std::enable_shared_from_this<view_interface_t>
{
public:
/**
Expand Down Expand Up @@ -164,19 +167,6 @@ class view_interface_t : public wf::signal::provider_t, public wf::object_base_t
*/
virtual void take_snapshot(wf::render_target_t& target);

/**
* View lifetime is managed by reference counting. To take a reference,
* use take_ref(). Note that one reference is automatically made when the
* view is created.
*/
void take_ref();

/**
* Drop a reference to the surface. When the reference count reaches 0, the
* destruct() method is called.
*/
void unref();

/**
* @return the wl_client associated with this surface, or null if the
* surface doesn't have a backing wlr_surface.
Expand All @@ -197,6 +187,7 @@ class view_interface_t : public wf::signal::provider_t, public wf::object_base_t

class view_priv_impl;
std::unique_ptr<view_priv_impl> priv;
static void initialize_new(wayfire_view view);

protected:
view_interface_t();
Expand Down Expand Up @@ -226,13 +217,6 @@ class view_interface_t : public wf::signal::provider_t, public wf::object_base_t
*/
virtual void deinitialize();

/**
* Called when the reference count reaches 0.
* It destructs the object and deletes it, so "this" may not be
* accessed after destruct() is called.
*/
virtual void destruct();

/**
* Emit the view map signal. It indicates that a view has been mapped, i.e.
* plugins can now "work" with it. Note that not all views will emit the map
Expand Down
17 changes: 0 additions & 17 deletions src/core/core-impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,6 @@ class compositor_core_impl_t : public compositor_core_t
*/
virtual void post_init();

/**
* Remove a view from the compositor list. This is called when the view's
* keep_count reaches zero for the first time after its creation.
*/
virtual void erase_view(wayfire_view view);

/**
* Find a view by its stringified ID.
* @return nullptr if no such view exists.
*/
virtual wayfire_view find_view(const std::string& id);

static compositor_core_impl_t& get();

wlr_seat *get_current_seat() override;
Expand All @@ -75,8 +63,6 @@ class compositor_core_impl_t : public compositor_core_t
override;
virtual wlr_cursor *get_wlr_cursor() override;

void add_view(std::unique_ptr<wf::view_interface_t> view) override;
std::vector<wayfire_view> get_all_views() override;
void focus_output(wf::output_t *o) override;
wf::output_t *get_active_output() override;
std::string get_xwayland_display() override;
Expand All @@ -94,9 +80,6 @@ class compositor_core_impl_t : public compositor_core_t
wf::wl_listener_wrapper idle_inhibitor_created;

wf::output_t *active_output = nullptr;
std::vector<std::unique_ptr<wf::view_interface_t>> views;
std::unordered_map<std::string, wayfire_view> id_to_view;

std::shared_ptr<scene::root_node_t> scene_root;

compositor_state_t state = compositor_state_t::UNKNOWN;
Expand Down
67 changes: 3 additions & 64 deletions src/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "wayfire/core.hpp"
#endif

#include <wayfire/nonstd/tracking-allocator.hpp>
#include "wayfire/scene.hpp"
#include <wayfire/workarea.hpp>
#include "wayfire/scene-operations.hpp"
Expand Down Expand Up @@ -397,68 +398,9 @@ wf::output_t*wf::compositor_core_impl_t::get_active_output()
return active_output;
}

void wf::compositor_core_impl_t::add_view(
std::unique_ptr<wf::view_interface_t> view)
std::vector<wayfire_view> wf::compositor_core_t::get_all_views()
{
auto v = view->self(); /* non-owning copy */
views.push_back(std::move(view));
id_to_view[std::to_string(v->get_id())] = v;

assert(active_output);

v->initialize();
if (!v->get_output())
{
v->set_output(active_output);
}

view_added_signal data;
data.view = v;
emit(&data);
}

std::vector<wayfire_view> wf::compositor_core_impl_t::get_all_views()
{
std::vector<wayfire_view> result;
for (auto& view : this->views)
{
result.push_back({view});
}

return result;
}

void wf::compositor_core_impl_t::erase_view(wayfire_view v)
{
if (!v)
{
return;
}

if (v->get_output())
{
v->set_output(nullptr);
}

wf::scene::remove_child(v->get_root_node());
auto it = std::find_if(views.begin(), views.end(),
[&v] (const auto& view) { return view.get() == v.get(); });

v->deinitialize();

id_to_view.erase(std::to_string(v->get_id()));
views.erase(it);
}

wayfire_view wf::compositor_core_impl_t::find_view(const std::string& id)
{
auto it = id_to_view.find(id);
if (it != id_to_view.end())
{
return it->second;
}

return nullptr;
return wf::tracking_allocator_t<view_interface_t>::get().get_all();
}

pid_t wf::compositor_core_impl_t::run(std::string command)
Expand Down Expand Up @@ -594,9 +536,6 @@ wf::compositor_core_impl_t::compositor_core_impl_t()
{}
wf::compositor_core_impl_t::~compositor_core_impl_t()
{
/* Unloading order is important. First we want to free any remaining views,
* then we destroy the input manager, and finally the rest is auto-freed */
views.clear();
input.reset();
output_layout.reset();
}
Expand Down
Loading

0 comments on commit 057bfc6

Please sign in to comment.