--- a/src/decoration.cpp +++ b/src/decoration.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "shell-theme.hpp" namespace wf @@ -92,7 +93,31 @@ wf::wl_idle_call idle_update_views; std::function update_event; wf::effect_hook_t pre_hook; - bool hook_set = false; + /* Outputs that currently have pre_hook registered, tracked per-output so + * hotplug and option changes cannot desync a single global flag. */ + std::set hook_outputs; + + bool effect_needs_hook() + { + return effect_animate || (std::string(effect_type) == "smoke") || + (std::string(effect_type) == "ink"); + } + + void add_pre_hook(wf::output_t *o) + { + if (hook_outputs.insert(o).second) + { + o->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); + } + } + + void remove_pre_hook(wf::output_t *o) + { + if (hook_outputs.erase(o)) + { + o->render->rem_effect(&pre_hook); + } + } wf::axis_callback shade_axis_cb; @@ -170,16 +195,16 @@ wf::signal::connection_t on_output_added = [=] (wf::output_added_signal *ev) { - if (effect_animate || (std::string(effect_type) == "smoke") || (std::string(effect_type) == "ink")) + if (effect_needs_hook()) { - ev->output->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); + add_pre_hook(ev->output); } }; wf::signal::connection_t on_output_removed = [=] (wf::output_removed_signal *ev) { - ev->output->render->rem_effect(&pre_hook); + remove_pre_hook(ev->output); }; void pop_transformer(wayfire_view view) @@ -473,14 +498,12 @@ } }; - if (std::string(effect_type) != "none") + if (effect_needs_hook()) { for (auto& o : wf::get_core().output_layout->get_outputs()) { - o->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); + add_pre_hook(o); } - - hook_set = true; } titlebar.set_callback([=] {recreate_frames();}); @@ -630,13 +653,11 @@ } } - if (hook_set) + for (auto& o : wf::get_core().output_layout->get_outputs()) { - for (auto& o : wf::get_core().output_layout->get_outputs()) - { - o->render->rem_effect(&pre_hook); - } + remove_pre_hook(o); } + hook_outputs.clear(); on_output_added.disconnect(); on_output_removed.disconnect(); @@ -676,27 +697,17 @@ void option_changed_cb(bool resize_decorations, bool recreate_decorations) { - if (effect_animate || (std::string(effect_type) == "smoke") || (std::string(effect_type) == "ink")) + if (effect_needs_hook()) { - if (!hook_set) + for (auto& o : wf::get_core().output_layout->get_outputs()) { - for (auto& o : wf::get_core().output_layout->get_outputs()) - { - o->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); - } - - hook_set = true; + add_pre_hook(o); } } else { - if (hook_set) + for (auto& o : wf::get_core().output_layout->get_outputs()) { - for (auto& o : wf::get_core().output_layout->get_outputs()) - { - o->render->rem_effect(&pre_hook); - } - - hook_set = false; + remove_pre_hook(o); } }