Task: Fix currency dialog responsiveness

Table of Contents

This page documents a task in the Make UI more responsive story. It captures the goal, current status, acceptance, and any notes or results.

Goal

Apply issues 1, 2, and 3 from the UI responsiveness story analysis to the currency dialogs (CurrencyDetailDialog, CurrencyHistoryDialog) as a proof-of-concept. If the pattern holds here, it can be rolled out to all other entities in subsequent tasks.

  • Issue 1 — Remove waitForFinished() from both dialog destructors. Replace with cancel() + disconnect only, so closing a dialog with in-flight NATS requests never blocks the UI thread.
  • Issue 2 — Add a localized tr("Loading…") placeholder entry to each combo box (roundingTypeCombo, monetaryNatureCombo, marketTierCombo) before the async fetch starts. Remove it and replace with real data when the future completes, eliminating the blank pop-in.
  • Issue 3 (partial) — CurrencyHistoryDialog destructor: apply the same waitForFinished() fix.

Issue 4 (thread-pool starvation) is out of scope for this task; it requires a cross-cutting ClientManager change.

Status

Field Value
State DONE
Parent story Make UI more responsive
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-06-01

Acceptance

  • CurrencyDetailDialog::~CurrencyDetailDialog() calls cancel() + disconnect on each watcher but does not call waitForFinished().
  • CurrencyHistoryDialog::~CurrencyHistoryDialog() (if it has watchers) applies the same fix.
  • roundingTypeCombo, monetaryNatureCombo, and marketTierCombo each show a localized tr("Loading…") item immediately when setClientManager() is called and the combo is in the fetching state; the item is removed and replaced with real data when the future finishes.
  • Opening and immediately closing a Currency dialog no longer freezes the UI (verified manually by timing or by inspection of the destructor code).
  • No regressions in the normal edit + save + delete flow.

Plan

(Transient implementation strategy. Written when work starts; distilled into the parent story's * Decisions and cleared when the task closes. Plans do not outlive their task.)

Notes

PRs

PR Title
#977 [agile] Scaffold UI responsiveness story T1: currency dialog fixes
#979 [ores.qt.refdata] Fix currency dialog responsiveness (T1 POC)

Review

# Comment summary File Decision Notes
1 Localize "Loading…" placeholder in Goal (i18n) task_fix_currency_dialog_responsiveness.org Fixed — use tr("Loading…") Gemini round 1
2 Localize "Loading…" in Acceptance criteria (i18n) task_fix_currency_dialog_responsiveness.org Fixed — use tr("Loading…") Gemini round 1
3 Race condition + guard: check for active roundingTypeWatcher CurrencyDetailDialog.cpp Fixed — guard + setObjectName Gemini round 1
4 Set object name on roundingTypeWatcher CurrencyDetailDialog.cpp Fixed — watcher->setObjectName Gemini round 1
5 Race condition + guard: check for active monetaryNatureWatcher CurrencyDetailDialog.cpp Fixed — guard + setObjectName Gemini round 1
6 Set object name on monetaryNatureWatcher CurrencyDetailDialog.cpp Fixed — watcher->setObjectName Gemini round 1
7 Race condition + guard: check for active marketTierWatcher CurrencyDetailDialog.cpp Fixed — guard + setObjectName Gemini round 1
8 Set object name on marketTierWatcher CurrencyDetailDialog.cpp Fixed — watcher->setObjectName Gemini round 1
9 Comments 3–8 re-opened by force-push after rebase Re-replied + re-resolved; no code change needed Gemini round 2

Result

Three fixes shipped in PR #979:

  1. waitForFinished() removed from CurrencyDetailDialog and CurrencyHistoryDialog destructors — closing a dialog with in-flight NATS requests no longer blocks the UI thread.
  2. tr("Loading…") placeholder added to roundingTypeCombo, monetaryNatureCombo, and marketTierCombo before each async fetch, with a named-watcher guard preventing concurrent fetches.
  3. QHeaderView::ResizeToContents replaced with Interactive in EntityListMdiWindow — eliminated a 24-second main-thread freeze on first open of any entity list window (all entities, not just currency). Root cause: ResizeToContents measured every cell on every layout pass; Interactive uses saved widths with no per-cell measurement.

Two ops recipes added: how to find environment log files; how to solve the postgres max connections error.

Emacs 29.1 (Org mode 9.6.6)