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]
|
// [font]
|
||||||
|
bool explicit_code_font = false;
|
||||||
|
bool explicit_writing_font = false;
|
||||||
if (auto sec = tbl["font"].as_table()) {
|
if (auto sec = tbl["font"].as_table()) {
|
||||||
if (auto v = (*sec)["name"].value<std::string>())
|
if (auto v = (*sec)["name"].value<std::string>())
|
||||||
font = *v;
|
font = *v;
|
||||||
if (auto v = (*sec)["size"].value<double>()) {
|
if (auto v = (*sec)["size"].value<double>()) {
|
||||||
if (*v > 0.0) font_size = static_cast<float>(*v);
|
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;
|
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;
|
writing_font = *v;
|
||||||
|
explicit_writing_font = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [appearance]
|
// [appearance]
|
||||||
@@ -131,6 +137,12 @@ GUIConfig::LoadFromTOML(const std::string &path)
|
|||||||
syntax = *v;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,6 +154,9 @@ GUIConfig::LoadFromINI(const std::string &path)
|
|||||||
if (!in.good())
|
if (!in.good())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool explicit_code_font = false;
|
||||||
|
bool explicit_writing_font = false;
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(in, line)) {
|
while (std::getline(in, line)) {
|
||||||
// Remove comments starting with '#' or ';'
|
// Remove comments starting with '#' or ';'
|
||||||
@@ -198,8 +213,10 @@ GUIConfig::LoadFromINI(const std::string &path)
|
|||||||
font = val;
|
font = val;
|
||||||
} else if (key == "code_font") {
|
} else if (key == "code_font") {
|
||||||
code_font = val;
|
code_font = val;
|
||||||
|
explicit_code_font = true;
|
||||||
} else if (key == "writing_font") {
|
} else if (key == "writing_font") {
|
||||||
writing_font = val;
|
writing_font = val;
|
||||||
|
explicit_writing_font = true;
|
||||||
} else if (key == "theme") {
|
} else if (key == "theme") {
|
||||||
theme = val;
|
theme = val;
|
||||||
} else if (key == "background" || key == "bg") {
|
} 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -577,9 +577,7 @@ GUIFrontend::Step(Editor &ed, bool &running)
|
|||||||
if (fr.CurrentFontName() != expected && fr.HasFont(expected)) {
|
if (fr.CurrentFontName() != expected && fr.HasFont(expected)) {
|
||||||
float sz = fr.CurrentFontSize();
|
float sz = fr.CurrentFontSize();
|
||||||
if (sz <= 0.0f) sz = config_.font_size;
|
if (sz <= 0.0f) sz = config_.font_size;
|
||||||
fr.LoadFont(expected, sz);
|
fr.RequestLoadFont(expected, sz);
|
||||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
|
||||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user