diff --git a/src/ui/windows/mining_benchmark.cpp b/src/ui/windows/mining_benchmark.cpp index 2a2762d..618a697 100644 --- a/src/ui/windows/mining_benchmark.cpp +++ b/src/ui/windows/mining_benchmark.cpp @@ -189,6 +189,11 @@ ThreadBenchmarkUpdate AdvanceThreadBenchmark(ThreadBenchmark& benchmark, update.startPoolMining = true; update.startThreads = benchmark.optimal_threads; } + } else { + // No candidate produced a nonzero hashrate (e.g. a pool that never + // reported a rate). Don't finish silently — flag the run as + // inconclusive so the caller can surface it (keeps this core pure). + update.inconclusive = true; } } break; diff --git a/src/ui/windows/mining_benchmark.h b/src/ui/windows/mining_benchmark.h index 2518034..b28ba31 100644 --- a/src/ui/windows/mining_benchmark.h +++ b/src/ui/windows/mining_benchmark.h @@ -56,6 +56,7 @@ struct ThreadBenchmarkUpdate { int startThreads = 0; bool saveOptimalThreads = false; int optimalThreads = 0; + bool inconclusive = false; // finished with no nonzero hashrate sample — caller should warn }; ThreadBenchmarkUpdate AdvanceThreadBenchmark(ThreadBenchmark& benchmark, diff --git a/src/ui/windows/mining_controls.cpp b/src/ui/windows/mining_controls.cpp index 9526d03..009fd02 100644 --- a/src/ui/windows/mining_controls.cpp +++ b/src/ui/windows/mining_controls.cpp @@ -176,8 +176,9 @@ void RenderMiningControls(App* app, const WalletState& state, const MiningInfo& idleRightEdge = gBtnX - 4.0f * dp; } - // Idle delay combo (to the left, when idle is enabled and NOT in thread scaling mode) - if (idleOn && !threadScaling) { + // Idle delay combo renderer (shared by the non-scaling and thread-scaling + // branches below). Draws right-aligned at idleRightEdge and advances it. + auto renderIdleDelayCombo = [&](const char* comboId) { struct DelayOption { int seconds; const char* label; }; static const DelayOption delays[] = { {30, "30s"}, {60, "1m"}, {120, "2m"}, {300, "5m"}, {600, "10m"} @@ -192,7 +193,7 @@ void RenderMiningControls(App* app, const WalletState& state, const MiningInfo& float comboY = curY + (headerH - ImGui::GetFrameHeight()) * 0.5f; ImGui::SetCursorScreenPos(ImVec2(comboX, comboY)); ImGui::SetNextItemWidth(comboW); - if (ImGui::BeginCombo("##IdleDelay", previewLabel, ImGuiComboFlags_NoArrowButton)) { + if (ImGui::BeginCombo(comboId, previewLabel, ImGuiComboFlags_NoArrowButton)) { for (const auto& d : delays) { bool selected = (d.seconds == curDelay); if (ImGui::Selectable(d.label, selected)) { @@ -206,6 +207,11 @@ void RenderMiningControls(App* app, const WalletState& state, const MiningInfo& if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_idle_delay")); idleRightEdge = comboX - 4.0f * dp; + }; + + // Idle delay combo (to the left, when idle is enabled and NOT in thread scaling mode) + if (idleOn && !threadScaling) { + renderIdleDelayCombo("##IdleDelay"); } // Thread scaling controls: idle delay + active threads / idle threads combos @@ -213,36 +219,7 @@ void RenderMiningControls(App* app, const WalletState& state, const MiningInfo& int hwThreads = std::max(1, (int)std::thread::hardware_concurrency()); // Idle delay combo - { - struct DelayOption { int seconds; const char* label; }; - static const DelayOption delays[] = { - {30, "30s"}, {60, "1m"}, {120, "2m"}, {300, "5m"}, {600, "10m"} - }; - int curDelay = app->settings()->getMineIdleDelay(); - const char* previewLabel = "2m"; - for (const auto& d : delays) { - if (d.seconds == curDelay) { previewLabel = d.label; break; } - } - float comboW = schema::UI().drawElement("components.settings-page", "idle-combo-width").sizeOr(64.0f); - float comboX = idleRightEdge - comboW; - float comboY = curY + (headerH - ImGui::GetFrameHeight()) * 0.5f; - ImGui::SetCursorScreenPos(ImVec2(comboX, comboY)); - ImGui::SetNextItemWidth(comboW); - if (ImGui::BeginCombo("##IdleDelayScale", previewLabel, ImGuiComboFlags_NoArrowButton)) { - for (const auto& d : delays) { - bool selected = (d.seconds == curDelay); - if (ImGui::Selectable(d.label, selected)) { - app->settings()->setMineIdleDelay(d.seconds); - app->settings()->save(); - } - if (selected) ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - if (ImGui::IsItemHovered()) - material::Tooltip("%s", TR("tt_idle_delay")); - idleRightEdge = comboX - 4.0f * dp; - } + renderIdleDelayCombo("##IdleDelayScale"); // Idle threads combo (threads when system is idle) { diff --git a/src/ui/windows/mining_tab.cpp b/src/ui/windows/mining_tab.cpp index b7296bc..6e86d56 100644 --- a/src/ui/windows/mining_tab.cpp +++ b/src/ui/windows/mining_tab.cpp @@ -248,6 +248,11 @@ static void RenderMiningTabContent(App* app) if (benchmarkUpdate.startPoolMining) { app->startPoolMining(benchmarkUpdate.startThreads); } + if (benchmarkUpdate.inconclusive) { + Notifications::instance().warning( + "Benchmark inconclusive: no hashrate samples were recorded. " + "Check the pool connection and try again."); + } } // ================================================================ diff --git a/src/ui/windows/request_payment_dialog.cpp b/src/ui/windows/request_payment_dialog.cpp index 557a9fd..3b82cd9 100644 --- a/src/ui/windows/request_payment_dialog.cpp +++ b/src/ui/windows/request_payment_dialog.cpp @@ -25,7 +25,6 @@ static char s_address[512] = ""; static double s_amount = 0.0; static char s_memo[512] = ""; static char s_label[128] = ""; -static int s_selected_addr_idx = -1; static std::string s_payment_uri; static uintptr_t s_qr_texture = 0; static int s_qr_width = 0; @@ -45,7 +44,6 @@ void RequestPaymentDialog::show(const std::string& address) s_amount = 0.0; s_memo[0] = '\0'; s_label[0] = '\0'; - s_selected_addr_idx = -1; s_uri_dirty = true; if (!address.empty()) { @@ -107,13 +105,13 @@ void RequestPaymentDialog::render(App* app) label = label.substr(0, zAddrFrontLbl.truncate) + "..." + label.substr(label.length() - zAddrBackLbl.truncate); } - if (ImGui::Selectable(label.c_str(), s_address == addr.address)) { + if (ImGui::Selectable(label.c_str(), addr.address == s_address)) { strncpy(s_address, addr.address.c_str(), sizeof(s_address) - 1); s_uri_dirty = true; } } } - + // T-addresses if (!state.t_addresses.empty()) { ImGui::TextDisabled("%s", TR("request_transparent_addrs")); @@ -124,7 +122,7 @@ void RequestPaymentDialog::render(App* app) label = label.substr(0, tAddrFrontLbl.truncate) + "..." + label.substr(label.length() - tAddrBackLbl.truncate); } - if (ImGui::Selectable(label.c_str(), s_address == addr.address)) { + if (ImGui::Selectable(label.c_str(), addr.address == s_address)) { strncpy(s_address, addr.address.c_str(), sizeof(s_address) - 1); s_uri_dirty = true; }