diff --git a/include/cuframes_composer/cpp/composer.hpp b/include/cuframes_composer/cpp/composer.hpp index bf16473..f376b76 100644 --- a/include/cuframes_composer/cpp/composer.hpp +++ b/include/cuframes_composer/cpp/composer.hpp @@ -134,6 +134,11 @@ private: std::string committed_signature_; std::string pending_signature_; + /* Manual override (PTZ через set_layout): пока now < manual_override_until_ms_ + * motion-mode "заморожен", композитор держит зафиксированный layout. */ + std::int64_t manual_override_until_ms_ = 0; + int manual_override_duration_ms_ = 60000; + /* Backward-compat overlay list (CLI overlays + detbox). */ std::vector overlays_; diff --git a/src/cpp/composer.cpp b/src/cpp/composer.cpp index 8bf2266..1f731df 100644 --- a/src/cpp/composer.cpp +++ b/src/cpp/composer.cpp @@ -114,11 +114,8 @@ void Composer::set_motion_mode(bool on, int ttl_ms) bool Composer::set_layout(const std::string& name) { - if (motion_mode_) { - std::fprintf(stderr, "[cfc/composer] set_layout('%s') ignored: motion_mode active\n", - name.c_str()); - return false; - } + /* В motion-mode set_layout не игнорируется: применяем + freezing motion + * на manual_override_duration_ms_ (default 60s). После — auto возврат. */ const auto& reg = current_templates(); auto it = std::find_if(reg.begin(), reg.end(), [&](const LayoutTemplate& t) { return t.name == name; }); @@ -131,9 +128,15 @@ bool Composer::set_layout(const std::string& name) pool_.for_each([&](PoolEntry& e) { snap.push_back(&e); }); std::sort(snap.begin(), snap.end(), [](PoolEntry* a, PoolEntry* b) { return a->priority > b->priority; }); + std::int64_t now = now_ms_mono(); layout_.apply(*it, snap, cfg_.width, cfg_.height); committed_signature_ = build_signature(it->name, snap); - committed_at_ms_ = now_ms_mono(); + committed_at_ms_ = now; + if (motion_mode_) { + manual_override_until_ms_ = now + manual_override_duration_ms_; + std::fprintf(stderr, "[cfc/composer] manual override '%s' до +%dms\n", + it->name.c_str(), manual_override_duration_ms_); + } return true; } @@ -207,6 +210,15 @@ void Composer::maybe_relayout() if (!motion_mode_) return; if (current_templates().empty()) return; + /* Manual override freeze. */ + std::int64_t now = now_ms_mono(); + if (manual_override_until_ms_ > now) return; + if (manual_override_until_ms_ != 0) { + std::fprintf(stderr, "[cfc/composer] manual override expired, возврат в motion-mode\n"); + manual_override_until_ms_ = 0; + committed_signature_.clear(); /* форс relayout */ + } + auto active = collect_active(); const LayoutTemplate* tpl = pick_best_fit(static_cast(active.size())); if (!tpl) return; @@ -266,7 +278,6 @@ void Composer::maybe_relayout() if (is_grow && nkeys.size() == ckeys.size()) is_grow = false; /* идентичны */ } - std::int64_t now = now_ms_mono(); if (is_grow) { layout_.apply(*tpl, active, cfg_.width, cfg_.height); committed_signature_ = sig;