Skip to content

Commit

Permalink
api: add collect_output_nodes() and use this in plugins (#1978)
Browse files Browse the repository at this point in the history
This function helps plugins to deal with always-on-top views.
  • Loading branch information
ammen99 authored Oct 25, 2023
1 parent ac5924e commit e86bbe8
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 29 deletions.
47 changes: 22 additions & 25 deletions plugins/common/wayfire/plugins/common/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,41 +67,38 @@ inline wf::geometry_t view_bounding_box_up_to(wayfire_view view,
*/
inline wayfire_toplevel_view find_output_view_at(wf::output_t *output, const wf::pointf_t& coords)
{
for (int i = int(wf::scene::layer::ALL_LAYERS) - 1; i >= 0; i--)
for (auto& output_node : wf::collect_output_nodes(wf::get_core().scene(), output))
{
for (auto& output_node : wf::get_core().scene()->layers[i]->get_children())
auto as_output = std::dynamic_pointer_cast<scene::output_node_t>(output_node);
if (!as_output || (as_output->get_output() != output) || !as_output->is_enabled())
{
auto as_output = std::dynamic_pointer_cast<scene::output_node_t>(output_node);
if (!as_output || (as_output->get_output() != output) || !as_output->is_enabled())
continue;
}

// We start the search directly from the output node's children. This is because the output nodes
// usually reject all queries outside of their current visible geometry, but we want to be able to
// query views from all workspaces, not just the current (and the only visible) one.
for (auto& ch : output_node->get_children())
{
if (!ch->is_enabled())
{
continue;
}

// We start the search directly from the output node's children. This is because the output nodes
// usually reject all queries outside of their current visible geometry, but we want to be able to
// query views from all workspaces, not just the current (and the only visible) one.
for (auto& ch : output_node->get_children())
{
if (!ch->is_enabled())
{
continue;
}

auto isec = ch->find_node_at(coords);
auto node = isec ? isec->node.get() : nullptr;
auto isec = ch->find_node_at(coords);
auto node = isec ? isec->node.get() : nullptr;

if (auto view = wf::toplevel_cast(wf::node_to_view(node)))
if (auto view = wf::toplevel_cast(wf::node_to_view(node)))
{
if (view->get_wset() == output->wset())
{
if (view->get_wset() == output->wset())
{
return view;
}
return view;
}
}

if (node)
{
return nullptr;
}
if (node)
{
return nullptr;
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/api/wayfire/output.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ class output_t : public wf::object_base_t, public wf::signal::provider_t
* output is currently focused, otherwise NULL.
*/
wayfire_view get_active_view_for_output(wf::output_t *output);

/**
* Collect all nodes which belong to an output from the scenegraph.
*/
std::vector<std::shared_ptr<scene::output_node_t>> collect_output_nodes(
wf::scene::node_ptr root, wf::output_t *output);
}

#endif /* end of include guard: OUTPUT_HPP */
2 changes: 1 addition & 1 deletion src/api/wayfire/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class plugin_interface_t
using wayfire_plugin_load_func = wf::plugin_interface_t * (*)();

/** The version of Wayfire's API/ABI */
constexpr uint32_t WAYFIRE_API_ABI_VERSION = 2023'10'21;
constexpr uint32_t WAYFIRE_API_ABI_VERSION = 2023'10'25;

/**
* Each plugin must also provide a function which returns the Wayfire API/ABI
Expand Down
32 changes: 32 additions & 0 deletions src/output/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,4 +464,36 @@ wayfire_view get_active_view_for_output(wf::output_t *output)

return nullptr;
}

void collect_output_nodes_recursive(wf::scene::node_ptr root, wf::output_t *output,
std::vector<std::shared_ptr<scene::output_node_t>>& result)
{
if (!root->is_enabled())
{
return;
}

if (auto output_node = std::dynamic_pointer_cast<scene::output_node_t>(root))
{
if (output_node->get_output() == output)
{
result.push_back(output_node);
}

return;
}

for (auto& ch : root->get_children())
{
collect_output_nodes_recursive(ch, output, result);
}
}

std::vector<std::shared_ptr<scene::output_node_t>> collect_output_nodes(
wf::scene::node_ptr root, wf::output_t *output)
{
std::vector<std::shared_ptr<scene::output_node_t>> res;
collect_output_nodes_recursive(root, output, res);
return res;
}
} // namespace wf
5 changes: 2 additions & 3 deletions src/output/workspace-stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ class workspace_stream_node_t::workspace_stream_instance_t : public scene::
push_damage(damage);
};

for (int layer = (int)scene::layer::ALL_LAYERS - 1; layer >= 0; layer--)
for (auto& output_node : wf::collect_output_nodes(wf::get_core().scene(), self->output))
{
auto layer_root = self->output->node_for_layer((scene::layer)layer);
for (auto& ch : layer_root->get_children())
for (auto& ch : output_node->get_children())
{
if (ch->is_enabled())
{
Expand Down

0 comments on commit e86bbe8

Please sign in to comment.