fix(ui): notification popup horizontal oscillation
Tamano FIJO del popup (Always + SizeConstraints) y flags NoResize/NoMove para evitar feedback loop entre auto-resize del popup y TextWrapped/SameLine internos. Reemplaza GetWindowContentRegionMax() por offsets explicitos calculados a partir del ancho fijo, ya que ese valor fluctua frame a frame con padding/borders y provocaba el ensanche/encogido continuo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -235,13 +235,23 @@ void toast_inbox_button(const char* id) {
|
|||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(spacing::sm, spacing::sm));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(spacing::sm, spacing::sm));
|
||||||
|
|
||||||
ImGui::SetNextWindowSize(ImVec2(360.0f, 0.0f), ImGuiCond_Appearing);
|
// Tamano FIJO del popup (Always + SizeConstraints) para evitar feedback
|
||||||
if (ImGui::BeginPopup(popup_id)) {
|
// loop entre auto-resize del popup y TextWrapped/SameLine internos.
|
||||||
// Header
|
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::PushStyleColor(ImGuiCol_Text, colors::text_muted);
|
||||||
ImGui::TextUnformatted("Notifications");
|
ImGui::TextUnformatted("Notifications");
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - 50.0f);
|
ImGui::SameLine(content_w - 50.0f);
|
||||||
if (ImGui::SmallButton("Clear")) {
|
if (ImGui::SmallButton("Clear")) {
|
||||||
toast_history_clear();
|
toast_history_clear();
|
||||||
snapshot.clear();
|
snapshot.clear();
|
||||||
@@ -254,7 +264,10 @@ void toast_inbox_button(const char* id) {
|
|||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
} else {
|
} else {
|
||||||
const auto now = std::chrono::steady_clock::now();
|
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
|
// Mostrar mas reciente arriba
|
||||||
for (auto it = snapshot.rbegin(); it != snapshot.rend(); ++it) {
|
for (auto it = snapshot.rbegin(); it != snapshot.rend(); ++it) {
|
||||||
const auto& t = *it;
|
const auto& t = *it;
|
||||||
@@ -262,9 +275,14 @@ void toast_inbox_button(const char* id) {
|
|||||||
ImGui::TextUnformatted(glyph_for(t.kind));
|
ImGui::TextUnformatted(glyph_for(t.kind));
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::SameLine();
|
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::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::TextUnformatted(format_age(t.created, now).c_str());
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|||||||
Reference in New Issue
Block a user