diff --git a/src/ui/windows/console_tab.cpp b/src/ui/windows/console_tab.cpp index d570099..f314eb9 100644 --- a/src/ui/windows/console_tab.cpp +++ b/src/ui/windows/console_tab.cpp @@ -370,7 +370,6 @@ void ConsoleTab::renderToolbar(ConsoleCommandExecutor& exec) // Auto-scroll toggle if (ImGui::Checkbox(TR("console_auto_scroll"), &auto_scroll_)) { if (auto_scroll_) { - scroll_to_bottom_ = true; new_lines_since_scroll_ = 0; } } @@ -382,15 +381,7 @@ void ConsoleTab::renderToolbar(ConsoleCommandExecutor& exec) // Log filters (daemon/errors/rpc-trace/app) apply only to a daemon log source. if (exec.hasLogFilters()) { // Daemon messages toggle - { - static bool s_prev_daemon_enabled = true; - ImGui::Checkbox(TR("console_daemon"), &s_daemon_messages_enabled); - // When toggling daemon filter while auto-scroll is active, scroll to bottom - if (s_prev_daemon_enabled != s_daemon_messages_enabled && auto_scroll_) { - scroll_to_bottom_ = true; - } - s_prev_daemon_enabled = s_daemon_messages_enabled; - } + ImGui::Checkbox(TR("console_daemon"), &s_daemon_messages_enabled); if (ImGui::IsItemHovered()) { material::Tooltip("%s", TR("console_show_daemon_output")); } @@ -400,15 +391,7 @@ void ConsoleTab::renderToolbar(ConsoleCommandExecutor& exec) ImGui::SameLine(); // Errors-only toggle - { - static bool s_prev_errors_only = false; - ImGui::Checkbox(TR("console_errors"), &s_errors_only_enabled); - // When toggling errors filter while auto-scroll is active, scroll to bottom - if (s_prev_errors_only != s_errors_only_enabled && auto_scroll_) { - scroll_to_bottom_ = true; - } - s_prev_errors_only = s_errors_only_enabled; - } + ImGui::Checkbox(TR("console_errors"), &s_errors_only_enabled); if (ImGui::IsItemHovered()) { material::Tooltip("%s", TR("console_show_errors_only")); } @@ -418,15 +401,8 @@ void ConsoleTab::renderToolbar(ConsoleCommandExecutor& exec) ImGui::SameLine(); // App RPC trace toggle — captures method/source only, never results or params - { - static bool s_prev_rpc_trace_enabled = false; - if (ImGui::Checkbox(TR("console_rpc_trace"), &s_rpc_trace_enabled)) { - rpc::RPCClient::setTraceEnabled(s_rpc_trace_enabled); - } - if (s_prev_rpc_trace_enabled != s_rpc_trace_enabled && auto_scroll_) { - scroll_to_bottom_ = true; - } - s_prev_rpc_trace_enabled = s_rpc_trace_enabled; + if (ImGui::Checkbox(TR("console_rpc_trace"), &s_rpc_trace_enabled)) { + rpc::RPCClient::setTraceEnabled(s_rpc_trace_enabled); } if (ImGui::IsItemHovered()) { material::Tooltip("%s", TR("console_show_rpc_trace")); @@ -437,14 +413,7 @@ void ConsoleTab::renderToolbar(ConsoleCommandExecutor& exec) ImGui::SameLine(); // App messages toggle — "[app] ..." wallet log lines - { - static bool s_prev_app_enabled = true; - ImGui::Checkbox(TR("console_app"), &s_app_messages_enabled); - if (s_prev_app_enabled != s_app_messages_enabled && auto_scroll_) { - scroll_to_bottom_ = true; - } - s_prev_app_enabled = s_app_messages_enabled; - } + ImGui::Checkbox(TR("console_app"), &s_app_messages_enabled); if (ImGui::IsItemHovered()) { material::Tooltip("%s", TR("console_show_app_output")); } @@ -716,7 +685,7 @@ void ConsoleTab::renderOutput() // Mouse press - start selection (use raw IO mouse state) if (mouse_in_output && io.MouseClicked[0]) { - sel_anchor_ = screenToTextPos(mouse_pos, line_height); + sel_anchor_ = screenToTextPos(mouse_pos); sel_end_ = sel_anchor_; is_selecting_ = true; has_selection_ = false; @@ -724,7 +693,7 @@ void ConsoleTab::renderOutput() // Mouse drag - extend selection (continue even if mouse leaves the window) if (is_selecting_ && io.MouseDown[0]) { - TextPos new_end = screenToTextPos(mouse_pos, line_height); + TextPos new_end = screenToTextPos(mouse_pos); sel_end_ = new_end; // Consider it a real selection once the position changes if (sel_end_.line != sel_anchor_.line || sel_end_.col != sel_anchor_.col) { @@ -734,7 +703,7 @@ void ConsoleTab::renderOutput() // Mouse release - finalize selection if (is_selecting_ && io.MouseReleased[0]) { - sel_end_ = screenToTextPos(mouse_pos, line_height); + sel_end_ = screenToTextPos(mouse_pos); is_selecting_ = false; } @@ -947,7 +916,6 @@ void ConsoleTab::renderOutput() // This ensures daemon output stays visible and scrolled to bottom if (auto_scroll_) { ImGui::SetScrollHereY(1.0f); - scroll_to_bottom_ = false; new_lines_since_scroll_ = 0; } @@ -964,8 +932,7 @@ void ConsoleTab::renderOutput() // Capture the hash/address under the cursor on right-click, for "Copy value". if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) { - TextPos tp = screenToTextPos(ImGui::GetMousePos(), - output_line_height_ > 0.0f ? output_line_height_ : line_height); + TextPos tp = screenToTextPos(ImGui::GetMousePos()); context_token_.clear(); if (tp.line >= 0 && tp.line < static_cast(lines_.size())) context_token_ = extractCopyableToken(lines_[tp.line].text, tp.col); @@ -1022,8 +989,7 @@ void ConsoleTab::renderOutput() dlInd->AddRect(iMin, iMax, IM_COL32(255, 218, 0, 120), 12.0f); char buf[48]; - snprintf(buf, sizeof(buf), TR("console_new_lines"), - new_lines_since_scroll_, new_lines_since_scroll_ != 1 ? "s" : ""); + snprintf(buf, sizeof(buf), TR("console_new_lines"), new_lines_since_scroll_); ImFont* capFont = Type().caption(); if (!capFont) capFont = ImGui::GetFont(); ImFont* icoFont = Type().iconSmall(); @@ -1044,13 +1010,12 @@ void ConsoleTab::renderOutput() ImGui::SetCursorScreenPos(iMin); if (ImGui::InvisibleButton("##scrollToBottom", ImVec2(indicW, indicH))) { auto_scroll_ = true; - scroll_to_bottom_ = true; new_lines_since_scroll_ = 0; } } } -ConsoleTab::TextPos ConsoleTab::screenToTextPos(ImVec2 screen_pos, float line_height) const +ConsoleTab::TextPos ConsoleTab::screenToTextPos(ImVec2 screen_pos) const { TextPos pos; @@ -1112,9 +1077,8 @@ ConsoleTab::TextPos ConsoleTab::screenToTextPos(ImVec2 screen_pos, float line_he ImFont* font = ImGui::GetFont(); float fontSize = ImGui::GetFontSize(); const char* segStart = text.c_str() + seg.byteStart; - const char* segEnd = text.c_str() + seg.byteEnd; int segLen = seg.byteEnd - seg.byteStart; - + // Walk characters within this segment for accurate positioning pos.col = seg.byteEnd; // default: past end of segment for (int c = 0; c < segLen; c++) { @@ -1569,7 +1533,12 @@ void ConsoleTab::addLine(const std::string& line, ImU32 color) std::string text = line; auto stripPrefix = [&text, &channel](const char* p, int ch) { const size_t n = std::strlen(p); - if (text.rfind(p, 0) == 0) { text.erase(0, n); channel = ch; } + if (text.rfind(p, 0) == 0) { + text.erase(0, n); + // Keep an error channel (red accent) for e.g. a "[daemon] error:" line so the + // bar matches the red text, rather than being downgraded to the source channel. + if (channel != CH_ERROR) channel = ch; + } }; stripPrefix("[daemon] ", CH_DAEMON); stripPrefix("[xmrig] ", CH_XMRIG); @@ -1602,8 +1571,6 @@ void ConsoleTab::addLine(const std::string& line, ImU32 color) if (!auto_scroll_) { new_lines_since_scroll_++; } - - scroll_to_bottom_ = auto_scroll_; } void ConsoleTab::addRpcTraceLine(const std::string& source, const std::string& method) @@ -1611,17 +1578,6 @@ void ConsoleTab::addRpcTraceLine(const std::string& source, const std::string& m addLine("[rpc] [" + rpcTraceTimestamp() + "] [" + source + "] " + method, COLOR_RPC); } -void ConsoleTab::addCommandResult(const std::string& cmd, const std::string& result, bool is_error) -{ - addLine("> " + cmd, COLOR_COMMAND); - - std::istringstream stream(result); - std::string line; - while (std::getline(stream, line)) { - addLine(line, is_error ? COLOR_ERROR : COLOR_RESULT); - } -} - void ConsoleTab::clear() { { diff --git a/src/ui/windows/console_tab.h b/src/ui/windows/console_tab.h index 56d5f9c..f4688ef 100644 --- a/src/ui/windows/console_tab.h +++ b/src/ui/windows/console_tab.h @@ -52,11 +52,6 @@ public: * @brief Clear console output */ void clear(); - - /** - * @brief Check if auto-scroll is enabled - */ - bool isAutoScrollEnabled() const { return auto_scroll_; } // Scanline effect toggle (set from settings) static bool s_scanline_enabled; @@ -98,7 +93,6 @@ private: int channel = CH_NONE; }; - void addCommandResult(const std::string& cmd, const std::string& result, bool is_error = false); // Format + color a completed command result (JSON-aware) into console lines. void addFormattedResult(const std::string& result, bool is_error); void renderStatusHeader(ConsoleCommandExecutor& exec); @@ -108,7 +102,6 @@ private: void renderCommandsPopup(); // Selection helpers - void handleSelection(); std::string getSelectedText() const; void clearSelection(); @@ -117,7 +110,7 @@ private: int line = -1; int col = 0; }; - TextPos screenToTextPos(ImVec2 screen_pos, float line_height) const; + TextPos screenToTextPos(ImVec2 screen_pos) const; bool isPosBeforeOrEqual(const TextPos& a, const TextPos& b) const; TextPos selectionStart() const; // Returns the earlier of sel_anchor_ and sel_end_ TextPos selectionEnd() const; // Returns the later of sel_anchor_ and sel_end_ @@ -127,7 +120,6 @@ private: int history_index_ = -1; char input_buffer_[4096] = {0}; bool auto_scroll_ = true; - bool scroll_to_bottom_ = false; float scroll_up_cooldown_ = 0.0f; // seconds to wait before re-enabling auto-scroll int new_lines_since_scroll_ = 0; // new lines while scrolled up (for indicator) // (log-ingestion cursors + result queue moved to the ConsoleCommandExecutor) diff --git a/src/util/i18n.cpp b/src/util/i18n.cpp index 9e415a1..2ace211 100644 --- a/src/util/i18n.cpp +++ b/src/util/i18n.cpp @@ -1223,17 +1223,6 @@ void I18n::loadBuiltinEnglish() strings_["daemon_update_downgrade_note"] = "Older versions may be incompatible with your current chain data. Installing a different version takes effect after a daemon restart."; // --- Lite Network tab (server browser) --- - strings_["lite_console_title"] = "Console"; - strings_["lite_console_intro"] = "Diagnostic log + interactive console. Type a command (e.g. info, balance, list) and press Enter; type help for the full list."; - strings_["lite_console_status"] = "Status:"; - strings_["lite_console_clear"] = "Clear"; - strings_["lite_console_copy"] = "Copy"; - strings_["lite_console_autoscroll"] = "Auto-scroll"; - strings_["lite_console_empty"] = "No output yet. Type a command (try 'help') and press Enter."; - strings_["lite_console_input_hint"] = "Type a command (help, info, balance, list, sync, new zs)…"; - strings_["lite_console_running"] = "running…"; - strings_["lite_console_busy"] = "A command is already running — wait for it to finish."; - strings_["lite_console_quit_note"] = "'quit'/'exit' don't apply here — the embedded backend stays running with the app."; strings_["lite_net_title"] = "Lite Servers"; strings_["lite_net_intro"] = "Pick a server to use, or let the wallet choose one at random. Changes apply immediately."; strings_["lite_net_use_random"] = "Use a random server each time";