diff --git a/src/wcm.cpp b/src/wcm.cpp index ed998c0..3f8985a 100644 --- a/src/wcm.cpp +++ b/src/wcm.cpp @@ -1,6 +1,8 @@ #include "wcm.hpp" #include "utils.hpp" +#include "ipc.hpp" #include "config-merge.hpp" +#include #include #include @@ -615,15 +617,55 @@ OptionWidget::OptionWidget(Option *option) : Gtk::Box(Gtk::ORIENTATION_HORIZONTA } else { auto combo_box = std::make_unique(); + std::set values; for (const auto & [name, str_value] : option->str_labels) { combo_box->append(str_value, name); + values.insert(str_value); if (str_value == wf_option->get_value_str()) { combo_box->set_active_id(str_value); } } + if (option->plugin->name == "wayfire-lock" && option->name == "lock_output") + { + // Preserve the saved/offline choice. Discovery only appends + // physical heads and never emits a selection/save operation. + auto selected = wf_option->get_value_str(); + if (values.insert(selected).second) + combo_box->append(selected, selected + " (disconnected)"); + combo_box->set_active_id(selected); + auto known = std::make_shared>(values); + signal_map().connect([this, widget = combo_box.get(), known] + { + discovery.send("window-rules/list-outputs", {}, [widget, known] (WcmIpcResult result) + { + if (!result.error.empty()) + { + widget->set_tooltip_text("Monitor discovery: " + result.error + ". The saved choice is retained."); + return; + } + auto outputs = result.reply; + for (size_t i = 0; i < outputs.size(); ++i) + { + auto output = outputs[i]; + auto append = [&] (const wf::json_reference_t& head) + { + auto name = head["name"].as_string(); + if (!name.empty() && known->insert(name).second) widget->append(name, name); + }; + if (output.has_member("members") && output["members"].size()) + { + auto members = output["members"]; + for (size_t j = 0; j < members.size(); ++j) append(members[j]); + } else append(output); + } + }); + }); + signal_unmap().connect([this] { discovery.cancel_observation(); }); + } + combo_box->signal_changed().connect( [=, widget = combo_box.get()] {