diff --git a/cpp/functions/core/toast.cpp b/cpp/functions/core/toast.cpp index a5d10f38..246b4b7f 100644 --- a/cpp/functions/core/toast.cpp +++ b/cpp/functions/core/toast.cpp @@ -235,13 +235,23 @@ void toast_inbox_button(const char* id) { ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(spacing::sm, spacing::sm)); - ImGui::SetNextWindowSize(ImVec2(360.0f, 0.0f), ImGuiCond_Appearing); - if (ImGui::BeginPopup(popup_id)) { - // Header + // Tamano FIJO del popup (Always + SizeConstraints) para evitar feedback + // loop entre auto-resize del popup y TextWrapped/SameLine internos. + constexpr float kInboxW = 360.0f; + constexpr float kInboxH = 380.0f; + ImGui::SetNextWindowSize(ImVec2(kInboxW, kInboxH), ImGuiCond_Always); + ImGui::SetNextWindowSizeConstraints(ImVec2(kInboxW, kInboxH), + ImVec2(kInboxW, kInboxH)); + if (ImGui::BeginPopup(popup_id, ImGuiWindowFlags_NoResize + | ImGuiWindowFlags_NoMove)) { + // Header — usar offset desde la izquierda calculado a partir del ancho + // FIJO del popup, NO de GetWindowContentRegionMax() (que cambia frame + // a frame con padding y provoca oscilacion horizontal). + const float content_w = kInboxW - 2.0f * spacing::sm; ImGui::PushStyleColor(ImGuiCol_Text, colors::text_muted); ImGui::TextUnformatted("Notifications"); ImGui::PopStyleColor(); - ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - 50.0f); + ImGui::SameLine(content_w - 50.0f); if (ImGui::SmallButton("Clear")) { toast_history_clear(); snapshot.clear(); @@ -254,7 +264,10 @@ void toast_inbox_button(const char* id) { ImGui::PopStyleColor(); } else { const auto now = std::chrono::steady_clock::now(); - ImGui::BeginChild("##inbox_list", ImVec2(0, 320.0f)); + // Reservar el espacio restante para la lista — alto fijo evita + // oscilacion vertical del popup. + ImGui::BeginChild("##inbox_list", ImVec2(content_w, 0.0f)); + const float list_w = ImGui::GetContentRegionAvail().x; // Mostrar mas reciente arriba for (auto it = snapshot.rbegin(); it != snapshot.rend(); ++it) { const auto& t = *it; @@ -262,9 +275,14 @@ void toast_inbox_button(const char* id) { ImGui::TextUnformatted(glyph_for(t.kind)); ImGui::PopStyleColor(); ImGui::SameLine(); - ImGui::TextWrapped("%s", t.text.c_str()); + // Wrap manual hasta x = list_w - 30 (espacio para el age), + // usando coordenadas del cursor relativas al window. + const float wrap_x = ImGui::GetCursorPosX() + (list_w - ImGui::GetCursorPosX()) - 36.0f; + ImGui::PushTextWrapPos(wrap_x); + ImGui::TextUnformatted(t.text.c_str()); + ImGui::PopTextWrapPos(); ImGui::PushStyleColor(ImGuiCol_Text, colors::text_dim); - ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - 30.0f); + ImGui::SameLine(list_w - 30.0f); ImGui::TextUnformatted(format_age(t.created, now).c_str()); ImGui::PopStyleColor(); ImGui::Separator();