Fix segfault from mid-frame font atlas rebuild
The edit-mode font switcher called LoadFont() directly between NewFrame() and Render(), invalidating the font atlas ImGui was actively using. Use RequestLoadFont() to defer the change to the safe inter-frame point, matching the existing zoom pattern. Also default code_font/writing_font to the main font when not explicitly configured, preventing a mismatch that triggered the switch on every first frame. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
29
GUIConfig.cc
29
GUIConfig.cc
@@ -99,16 +99,22 @@ GUIConfig::LoadFromTOML(const std::string &path)
|
||||
}
|
||||
|
||||
// [font]
|
||||
bool explicit_code_font = false;
|
||||
bool explicit_writing_font = false;
|
||||
if (auto sec = tbl["font"].as_table()) {
|
||||
if (auto v = (*sec)["name"].value<std::string>())
|
||||
font = *v;
|
||||
if (auto v = (*sec)["size"].value<double>()) {
|
||||
if (*v > 0.0) font_size = static_cast<float>(*v);
|
||||
}
|
||||
if (auto v = (*sec)["code"].value<std::string>())
|
||||
if (auto v = (*sec)["code"].value<std::string>()) {
|
||||
code_font = *v;
|
||||
if (auto v = (*sec)["writing"].value<std::string>())
|
||||
explicit_code_font = true;
|
||||
}
|
||||
if (auto v = (*sec)["writing"].value<std::string>()) {
|
||||
writing_font = *v;
|
||||
explicit_writing_font = true;
|
||||
}
|
||||
}
|
||||
|
||||
// [appearance]
|
||||
@@ -131,6 +137,12 @@ GUIConfig::LoadFromTOML(const std::string &path)
|
||||
syntax = *v;
|
||||
}
|
||||
|
||||
// Default code_font to the main font if not explicitly set
|
||||
if (!explicit_code_font)
|
||||
code_font = font;
|
||||
if (!explicit_writing_font && writing_font == "crimsonpro" && font != "default")
|
||||
writing_font = font;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,6 +154,9 @@ GUIConfig::LoadFromINI(const std::string &path)
|
||||
if (!in.good())
|
||||
return false;
|
||||
|
||||
bool explicit_code_font = false;
|
||||
bool explicit_writing_font = false;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
// Remove comments starting with '#' or ';'
|
||||
@@ -198,8 +213,10 @@ GUIConfig::LoadFromINI(const std::string &path)
|
||||
font = val;
|
||||
} else if (key == "code_font") {
|
||||
code_font = val;
|
||||
explicit_code_font = true;
|
||||
} else if (key == "writing_font") {
|
||||
writing_font = val;
|
||||
explicit_writing_font = true;
|
||||
} else if (key == "theme") {
|
||||
theme = val;
|
||||
} else if (key == "background" || key == "bg") {
|
||||
@@ -222,5 +239,13 @@ GUIConfig::LoadFromINI(const std::string &path)
|
||||
}
|
||||
}
|
||||
|
||||
// If code_font was not explicitly set, default it to the main font
|
||||
// so that the edit-mode font switcher doesn't immediately switch away
|
||||
// from the font loaded during Init.
|
||||
if (!explicit_code_font)
|
||||
code_font = font;
|
||||
if (!explicit_writing_font && writing_font == "crimsonpro" && font != "default")
|
||||
writing_font = font;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -577,9 +577,7 @@ GUIFrontend::Step(Editor &ed, bool &running)
|
||||
if (fr.CurrentFontName() != expected && fr.HasFont(expected)) {
|
||||
float sz = fr.CurrentFontSize();
|
||||
if (sz <= 0.0f) sz = config_.font_size;
|
||||
fr.LoadFont(expected, sz);
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
fr.RequestLoadFont(expected, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user