From 04252a3c966ea889c2931cfecd7b1d63a07307b6 Mon Sep 17 00:00:00 2001 From: sysadmin Date: Wed, 4 Feb 2026 09:28:12 -0700 Subject: [PATCH] Fix type picker popup cursor, sanitize string display - Use isListActive() to detect popup and force arrow cursor - Remove broken widget-search hack from showTypeListFiltered() - Escape \n \r \t and control chars in char[]/wchar_t[] display --- src/editor.cpp | 22 ++++++++++++---------- src/format.cpp | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/editor.cpp b/src/editor.cpp index ebad48e..94bff40 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1143,16 +1143,7 @@ void RcxEditor::showTypeListFiltered(const QString& filter) { m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCSETSEPARATOR, (long)' '); m_sci->SendScintilla(QsciScintillaBase::SCI_USERLISTSHOW, (uintptr_t)1, list.constData()); - - // Set arrow cursor on the autocomplete popup (it defaults to pointing hand) - for (QObject* child : m_sci->children()) { - if (auto* w = qobject_cast(child)) { - if (w->isVisible() && w->windowFlags() & Qt::Popup) { - w->setCursor(Qt::ArrowCursor); - break; - } - } - } + // Arrow cursor for popup is handled by applyHoverCursor() via isListActive() } void RcxEditor::updateTypeListFilter() { @@ -1248,6 +1239,17 @@ void RcxEditor::applyHoverCursor() { return; } + // If autocomplete/user list popup is active, use arrow cursor + if (m_sci->isListActive()) { + if (!m_cursorOverridden) { + QApplication::setOverrideCursor(Qt::ArrowCursor); + m_cursorOverridden = true; + } else { + QApplication::changeOverrideCursor(Qt::ArrowCursor); + } + return; + } + int line; EditTarget t; bool tokenHit = hitTestTarget(m_sci, m_meta, m_lastHoverPos, line, t, m_layout.nameW); diff --git a/src/format.cpp b/src/format.cpp index 32eb2d1..3177925 100644 --- a/src/format.cpp +++ b/src/format.cpp @@ -107,6 +107,21 @@ QString fmtStructFooter(const Node& node, int depth, int totalSize) { static inline bool isAsciiPrintable(uint8_t c) { return c >= 0x20 && c <= 0x7E; } +// Escape control characters for display +static QString sanitizeString(const QString& s) { + QString out; + out.reserve(s.size() + 8); + for (QChar c : s) { + if (c == '\n') out += QStringLiteral("\\n"); + else if (c == '\r') out += QStringLiteral("\\r"); + else if (c == '\t') out += QStringLiteral("\\t"); + else if (c == '\\') out += QStringLiteral("\\\\"); + else if (c < QChar(0x20)) out += QStringLiteral("\\x") + QString::number(c.unicode(), 16); + else out += c; + } + return out; +} + static QString bytesToAscii(const QByteArray& b, int slot) { QString out; out.reserve(slot); @@ -189,6 +204,7 @@ static QString readValueImpl(const Node& node, const Provider& prov, int end = bytes.indexOf('\0'); if (end >= 0) bytes.truncate(end); QString s = QString::fromUtf8(bytes); + if (display) s = sanitizeString(s); return display ? (QStringLiteral("\"") + s + QStringLiteral("\"")) : s; } case NodeKind::UTF16: { @@ -197,6 +213,7 @@ static QString readValueImpl(const Node& node, const Provider& prov, bytes.size() / 2); int end = s.indexOf(QChar(0)); if (end >= 0) s.truncate(end); + if (display) s = sanitizeString(s); return display ? (QStringLiteral("L\"") + s + QStringLiteral("\"")) : s; } default: