From d7e35727f17e998703cfbb00ac8647705fb56c7d Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Wed, 25 Mar 2026 02:07:31 -0700 Subject: [PATCH] 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) --- GUIConfig.cc | 29 +++++++++++++++++++++++++++-- ImGuiFrontend.cc | 4 +--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/GUIConfig.cc b/GUIConfig.cc index ac62dc7..daf1f54 100644 --- a/GUIConfig.cc +++ b/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()) font = *v; if (auto v = (*sec)["size"].value()) { if (*v > 0.0) font_size = static_cast(*v); } - if (auto v = (*sec)["code"].value()) + if (auto v = (*sec)["code"].value()) { code_font = *v; - if (auto v = (*sec)["writing"].value()) + explicit_code_font = true; + } + if (auto v = (*sec)["writing"].value()) { 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; } diff --git a/ImGuiFrontend.cc b/ImGuiFrontend.cc index d21175f..57a961f 100644 --- a/ImGuiFrontend.cc +++ b/ImGuiFrontend.cc @@ -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); } } }