fix(preferences): retain MIDI device labels across dropdown refreshes

This commit is contained in:
Johannes Findeisen 2026-11-06 02:43:56 +01:00
commit 8795516124
4 changed files with 57 additions and 1 deletions

View file

@ -399,8 +399,38 @@ int midi_workflow_tests()
CHECK(xtc_settings_load(&saved,config.c_str())==XTC_ERR_FORMAT);
unlink(config.c_str());rmdir(dir);puts("MIDI workflow/configuration GUI checks passed.");return failures ? 1 : 0;
}
int midi_device_label_tests()
{
xtc_settings settings{},applied{};xtc_settings_defaults(&settings);unsigned int generation=0;
auto names=[&](bool input){return std::vector<std::string>{
std::string(input ? "Controller / USB keyboard: MIDI output " : "Synth / USB interface: MIDI input ")+std::string(120,'A'+static_cast<char>(generation)),
input ? "Keyboard:out 2" : "Synth:in 2"};};
PreferencesDialog dialog(settings,"",[&](const xtc_settings &s){applied=s;return XTC_OK;},names);
auto *input=dynamic_cast<Fl_Input_Choice *>(find(&dialog,"Default MIDI input source (next Play)"));
auto *output=dynamic_cast<Fl_Input_Choice *>(find(&dialog,"Default MIDI output destination (next Play)"));
CHECK(input && output);if(!input || !output)return 1;
for(unsigned int pass=0;pass<4;++pass){
if(pass){generation=pass;press(find(&dialog,"Refresh MIDI devices"));}
// Force reuse of temporary string allocations after enumeration returns.
std::vector<std::string> churn(256,std::string(200,'z'));
for(auto pair:{std::pair<Fl_Input_Choice *,bool>{input,true},{output,false}}){
auto expected=names(pair.second);auto *menu=pair.first->menubutton();
CHECK(menu->size()==4 && !strcmp(menu->menu()[0].label(),"(None)"));
for(size_t i=0;i<expected.size();++i)CHECK(!strcmp(menu->menu()[i+1].label(),expected[i].c_str()));
menu->picked(menu->menu()+1);CHECK(pair.first->value()==expected[0]);
}
press(find(&dialog,"Apply"));
CHECK(applied.midi_input_port==names(true)[0] && applied.midi_output_port==names(false)[0]);
}
auto selected=std::string(input->value());generation=5;press(find(&dialog,"Refresh MIDI devices"));
CHECK(input->value()==selected); // A disconnected device remains remembered.
for(auto *choice:{input,output}){choice->menubutton()->picked(choice->menubutton()->menu());CHECK(!*choice->value());}
press(find(&dialog,"Apply"));CHECK(!applied.midi_input_port[0] && !applied.midi_output_port[0]);
puts("MIDI device dropdown labels/selection/refresh checks passed.");return failures ? 1 : 0;
}
int main(int argc, char **argv)
{
if(std::getenv("XTC_TEST_MIDI_LABELS_ONLY"))return midi_device_label_tests();
if(std::getenv("XTC_TEST_MIDI_WORKFLOWS_ONLY"))return midi_workflow_tests();
if(std::getenv("XTC_TEST_CREATIVE_ONLY"))return creative_workflow_tests();
if(std::getenv("XTC_TEST_TRACK_FX_ONLY"))return track_insert_tests();