From 57df48a8e0cdf7f2580f26725f529f645899d849 Mon Sep 17 00:00:00 2001 From: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com> Date: Fri, 30 Oct 2026 05:18:33 +0800 Subject: [PATCH 1/2] diag(qt): log input-method events behind TERMFORGE_QT_IME_LOG refs #155 Records kind and UTF-8 bytes for preedit, commit and cancel so a fixed-IME run can show what the widget delivered without changing the send path. --- src/qt/terminal_widget.hpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/qt/terminal_widget.hpp b/src/qt/terminal_widget.hpp index 107d10a3..f5ca894e 100644 --- a/src/qt/terminal_widget.hpp +++ b/src/qt/terminal_widget.hpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include namespace termforge::qt { @@ -135,11 +137,31 @@ class TerminalWidget final : public QWidget { if (query == Qt::ImCursorPosition) return 0; return QWidget::inputMethodQuery(query); } + // Opt-in observation for the fixed-IME runs: records exactly which kind of + // input-method event arrived and the UTF-8 bytes it carried. Unset by + // default so ordinary runs touch no file. + static void ime_log(const char* kind, const QString& text) { + static const char* path = std::getenv("TERMFORGE_QT_IME_LOG"); + if (path == nullptr) return; + FILE* stream = std::fopen(path, "ab"); + if (stream == nullptr) return; + const QByteArray bytes = text.toUtf8(); + std::fprintf(stream, "{\"kind\":\"%s\",\"bytes\":%d,\"utf8\":\"", kind, static_cast(bytes.size())); + for (const char ch : bytes) std::fprintf(stream, "%02x", static_cast(ch)); + std::fprintf(stream, "\"}\n"); + std::fclose(stream); + } void inputMethodEvent(QInputMethodEvent* event) override { const QString preedit = event->preeditString(); - if (preedit != preedit_) { preedit_ = preedit; update(); } + if (preedit != preedit_) { + if (!preedit.isEmpty()) ime_log("preedit", preedit); + else if (!preedit_.isEmpty()) ime_log("cancel", QString()); + preedit_ = preedit; + update(); + } const QString commit = event->commitString(); if (!commit.isEmpty()) { + ime_log("commit", commit); model_.send(commit.toUtf8()); preedit_.clear(); update(); From 29a6a73e9cd8d1045673ebe84ec2419cd638916f Mon Sep 17 00:00:00 2001 From: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com> Date: Fri, 30 Oct 2026 05:23:29 +0800 Subject: [PATCH 2/2] diag(qt): record the caret cell and widget origin with IME events refs #155 The caret cell is what the IME uses to place its candidate window, so the log now carries row, column, widget-relative caret rectangle and the widget global origin for each event. --- src/qt/terminal_widget.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/qt/terminal_widget.hpp b/src/qt/terminal_widget.hpp index f5ca894e..b1316741 100644 --- a/src/qt/terminal_widget.hpp +++ b/src/qt/terminal_widget.hpp @@ -1,4 +1,4 @@ -// Qt terminal geometry follows the current font; semantics stay in the model. +// Qt terminal geometry follows the current font; semantics stay in the model. #pragma once #include "terminal_session.hpp" @@ -140,15 +140,20 @@ class TerminalWidget final : public QWidget { // Opt-in observation for the fixed-IME runs: records exactly which kind of // input-method event arrived and the UTF-8 bytes it carried. Unset by // default so ordinary runs touch no file. - static void ime_log(const char* kind, const QString& text) { + void ime_log(const char* kind, const QString& text) { static const char* path = std::getenv("TERMFORGE_QT_IME_LOG"); if (path == nullptr) return; FILE* stream = std::fopen(path, "ab"); if (stream == nullptr) return; const QByteArray bytes = text.toUtf8(); + const auto& screen = model_.screen(); + const QPoint origin = mapToGlobal(QPoint(0, 0)); std::fprintf(stream, "{\"kind\":\"%s\",\"bytes\":%d,\"utf8\":\"", kind, static_cast(bytes.size())); for (const char ch : bytes) std::fprintf(stream, "%02x", static_cast(ch)); - std::fprintf(stream, "\"}\n"); + std::fprintf(stream, "\",\"row\":%d,\"column\":%d,\"caret_x\":%d,\"caret_y\":%d,\"caret_w\":%d,\"caret_h\":%d,\"origin_x\":%d,\"origin_y\":%d}\n", + screen.row, screen.column, + margin + screen.column * cell_width_, margin + screen.row * cell_height_, + cell_width_, cell_height_, origin.x(), origin.y()); std::fclose(stream); } void inputMethodEvent(QInputMethodEvent* event) override {