diff --git a/plugins/window-rules/view-action-interface.cpp b/plugins/window-rules/view-action-interface.cpp index eb973280..839c9fb5 100644 --- a/plugins/window-rules/view-action-interface.cpp +++ b/plugins/window-rules/view-action-interface.cpp @@ -6,6 +6,7 @@ #include "wayfire/plugins/grid.hpp" #include "wayfire/util/log.hpp" #include "wayfire/view-transform.hpp" +#include #include #include @@ -16,7 +17,9 @@ namespace wf { view_action_interface_t::~view_action_interface_t() -{} +{ + _view->erase_data("wm-actions-above"); +} bool view_action_interface_t::execute(const std::string & name, const std::vector & args) @@ -173,6 +176,14 @@ bool view_action_interface_t::execute(const std::string & name, } return true; + } else if (name == "sticky") + { + _make_sticky(); + return false; + } else if (name == "always_on_top") + { + _always_on_top(); + return false; } LOGE("View action interface: Unsupported action execution requested. Name: ", @@ -186,6 +197,11 @@ void view_action_interface_t::set_view(wayfire_view view) _view = view; } +void view_action_interface_t::set_above_layer(nonstd::observer_ptr always_above) +{ + _always_above = always_above; +} + void view_action_interface_t::_maximize() { _view->tile_request(wf::TILED_EDGES_ALL); @@ -206,6 +222,41 @@ void view_action_interface_t::_unminimize() _view->set_minimized(false); } +void view_action_interface_t::_make_sticky() +{ + _view->set_sticky(1); +} + +void view_action_interface_t::_always_on_top() +{ + if (!_view) + { + return; + } + + auto output = _view->get_output(); + if (!output) + { + return; + } + + if (_view->has_data("wm-actions-above")) + { + output->workspace->add_view(_view, + (wf::layer_t)output->workspace->get_view_layer(_view)); + _view->erase_data("wm-actions-above"); + } else + { + output->workspace->add_view_to_sublayer(_view, _always_above); + _view->store_data(std::make_unique(), + "wm-actions-above"); + } + + wf::_view_signal data; + data.view = _view; + output->emit_signal("wm-actions-above-changed", &data); +} + std::tuple view_action_interface_t::_expect_float( const std::vector & args, std::size_t position) { diff --git a/plugins/window-rules/view-action-interface.hpp b/plugins/window-rules/view-action-interface.hpp index 26c34bc7..0f23607d 100644 --- a/plugins/window-rules/view-action-interface.hpp +++ b/plugins/window-rules/view-action-interface.hpp @@ -3,6 +3,7 @@ #include "wayfire/action/action_interface.hpp" #include "wayfire/view.hpp" +#include #include #include #include @@ -18,12 +19,15 @@ class view_action_interface_t : public action_interface_t const std::vector & args) override; void set_view(wayfire_view view); + void set_above_layer(nonstd::observer_ptr always_above); private: void _maximize(); void _unmaximize(); void _minimize(); void _unminimize(); + void _make_sticky(); + void _always_on_top(); std::tuple _expect_float(const std::vector & args, std::size_t position); @@ -51,6 +55,7 @@ class view_action_interface_t : public action_interface_t wf::geometry_t _get_workspace_grid_geometry(wf::output_t *output) const; wayfire_view _view; + nonstd::observer_ptr _always_above; }; } // End namespace wf. diff --git a/plugins/window-rules/window-rules.cpp b/plugins/window-rules/window-rules.cpp index 295dd798..723b2f16 100644 --- a/plugins/window-rules/window-rules.cpp +++ b/plugins/window-rules/window-rules.cpp @@ -26,6 +26,7 @@ class wayfire_window_rules_t : public wf::plugin_interface_t void apply(const std::string & signal, wf::signal_data_t *data); private: + nonstd::observer_ptr always_above; void setup_rules_from_config(); wf::lexer_t _lexer; @@ -87,6 +88,9 @@ void wayfire_window_rules_t::init() output->connect_signal("view-minimized", &_minimized); output->connect_signal("view-fullscreen", &_fullscreened); wf::get_core().connect_signal("reload-config", &_reload_config); + + always_above = output->workspace->create_sublayer( + wf::LAYER_WORKSPACE, wf::SUBLAYER_DOCKED_ABOVE); } void wayfire_window_rules_t::fini() @@ -96,6 +100,15 @@ void wayfire_window_rules_t::fini() { wf::get_core().erase_data(); } + auto always_on_top_views = + output->workspace->get_views_in_sublayer(always_above); + + for (auto view : always_on_top_views) + { + view->erase_data("wm-actions-above"); + } + + output->workspace->destroy_sublayer(always_above); } void wayfire_window_rules_t::apply(const std::string & signal, @@ -128,6 +141,7 @@ void wayfire_window_rules_t::apply(const std::string & signal, { _access_interface.set_view(view); _action_interface.set_view(view); + _action_interface.set_above_layer(always_above); auto error = rule->apply(signal, _access_interface, _action_interface); if (error) { @@ -200,10 +214,11 @@ void wayfire_window_rules_t::setup_rules_from_config() { _lexer.reset(opt->get_value_str()); auto rule = wf::rule_parser_t().parse(_lexer); - if (rule != nullptr) + if (!rule) { - _rules.push_back(rule); + continue; } + _rules.push_back(rule); } }