Reset device selection on agent swap or unload (#124)

set_live_printer_agent centralizes
the swap: deselect the machine,
clear stale sidebar state and the
previous agent's Other Devices, then
install the new agent (or null when
its provider vanished). Plugin
load/unload callbacks refresh the
dropdown and re-run agent selection.
load_last_machine no longer falls
back to the first available machine.
This commit is contained in:
Andrew
2026-07-16 16:27:53 +08:00
committed by Ian Chua
parent 75a2460649
commit b2f08c3ff8
6 changed files with 150 additions and 47 deletions

View File

@@ -2809,16 +2809,58 @@ void GUI_App::init_plugin_gui_wiring()
});
};
// why: a newly loaded plugin only adds a selectable agent
// refresh the dropdown and leave the live agent alone
auto refresh_printer_agent_dropdown_after_load = [](const std::string&)
{
if (!wxTheApp)
return;
GUI_App* app = &GUI::wxGetApp();
if (app->is_closing())
return;
app->CallAfter([app]
{
if (!app->is_closing())
app->refresh_printer_agent_dropdown();
});
};
// why: the unloaded plugin may have been the provider of the live agent
// re-run selection, where a now-missing agent will be cleared
// refresh dropdown after
auto switch_printer_agent_after_unload = [](const std::string&)
{
if (!wxTheApp)
return;
GUI_App* app = &GUI::wxGetApp();
if (app->is_closing())
return;
app->CallAfter([app] {
if (app->is_closing())
return;
app->switch_printer_agent();
app->refresh_printer_agent_dropdown();
});
};
plugin_mgr.subscribe_on_unload_callback(PluginHostUi::close_windows_for_plugin);
plugin_mgr.subscribe_on_load_callback([refresh_plugins_dialog](const std::string&) { refresh_plugins_dialog(); });
plugin_mgr.subscribe_on_unload_callback([refresh_plugins_dialog](const std::string&) { refresh_plugins_dialog(); });
plugin_mgr.subscribe_on_load_callback(NetworkAgentFactory::register_python_plugin);
plugin_mgr.subscribe_on_unload_callback(NetworkAgentFactory::deregister_python_plugin);
plugin_mgr.subscribe_on_load_callback(refresh_printer_agent_dropdown_after_load);
plugin_mgr.subscribe_on_unload_callback(switch_printer_agent_after_unload);
plugin_mgr.subscribe_on_capability_load_callback(
[refresh_plugins_dialog](const PluginCapabilityId& capability) {
[refresh_plugins_dialog, refresh_printer_agent_dropdown_after_load](const PluginCapabilityId& capability) {
if (capability.type == PluginCapabilityType::PrinterConnection)
NetworkAgentFactory::register_python_printer_agent(capability.plugin_key, capability.name);
refresh_plugins_dialog();
refresh_printer_agent_dropdown_after_load(capability.plugin_key);
// A newly loaded capability may satisfy a missing-plugin notification; re-validate the
// current plate (on the UI thread) so the notification clears once its plugin is available.
if (wxTheApp && !wxGetApp().is_closing())
@@ -2828,10 +2870,11 @@ void GUI_App::init_plugin_gui_wiring()
});
});
plugin_mgr.subscribe_on_capability_unload_callback(
[refresh_plugins_dialog](const PluginCapabilityId& capability) {
[refresh_plugins_dialog, switch_printer_agent_after_unload](const PluginCapabilityId& capability) {
if (capability.type == PluginCapabilityType::PrinterConnection)
NetworkAgentFactory::deregister_python_printer_agent(capability.plugin_key, capability.name);
refresh_plugins_dialog();
switch_printer_agent_after_unload(capability.plugin_key);
});
}
@@ -3873,6 +3916,36 @@ unsigned GUI_App::get_colour_approx_luma(const wxColour &colour)
));
}
void GUI_App::refresh_printer_agent_dropdown()
{
if (Tab* tab = get_tab(Preset::TYPE_PRINTER))
{
if (auto* printer_tab = dynamic_cast<TabPrinter*>(tab))
printer_tab->refresh_printer_agent_dropdown();
}
}
void GUI_App::set_live_printer_agent(std::shared_ptr<IPrinterAgent> agent)
{
if (!m_agent)
return;
// why: tearing down the old machine selection is only ever the prefix of setting the live
// agent (to a new one, or to null when the selection is missing) - so it lives here, not as
// a standalone helper. Pass nullptr to clear the selection.
if (DeviceManager* dev = getDeviceManager())
{
dev->set_selected_machine(""); // why: empty id disconnects and deselects the current machine
m_agent->set_user_selected_machine("");
// note: belt-and-suspenders (precedent: DeviceManagerRefresher::on_timer)
dev->OnSelectedMachineLost(); // why: clear stale sidebar sync-status / AMS
dev->clear_other_devices(); // why: drop stale LAN discoveries; keep My Devices
}
m_agent->set_printer_agent(agent);
sidebar().update_all_preset_comboboxes();
}
std::string GUI_App::resolve_printer_agent_id(const std::string& stored_id)
{
if (!stored_id.empty())
@@ -3898,9 +3971,11 @@ void GUI_App::switch_printer_agent()
// Check if agent is registered
const PrinterAgentInfo* agent_info_ptr = NetworkAgentFactory::get_printer_agent_info(effective_agent_id);
if (!agent_info_ptr) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": unregistered agent ID '" << effective_agent_id
<< "', keeping current agent";
// Keep current agent, don't switch
// why: the selected agent's provider is gone (e.g. plugin unloaded); leaving the old
// live agent up would keep talking to a machine the user can no longer select.
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": agent ID '" << effective_agent_id
<< "' is unregistered; clearing live printer agent";
set_live_printer_agent(nullptr);
return;
}
const PrinterAgentInfo agent_info = *agent_info_ptr;
@@ -3914,7 +3989,9 @@ void GUI_App::switch_printer_agent()
NetworkAgentFactory::create_printer_agent_by_id(effective_agent_id, cloud_agent, log_dir);
if (!new_printer_agent) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": failed to create agent '" << effective_agent_id << "', keeping current agent";
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": failed to create agent '" << effective_agent_id
<< "'; clearing live printer agent";
set_live_printer_agent(nullptr);
return;
}
@@ -3937,9 +4014,9 @@ void GUI_App::switch_printer_agent()
return;
}
// Swap the agent
m_agent->set_printer_agent(new_printer_agent);
sidebar().update_all_preset_comboboxes();
// Swap the agent; set_live_printer_agent resets the device selection so the new
// agent starts clean (#124).
set_live_printer_agent(new_printer_agent);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": printer agent switched to " << effective_agent_id;