bug#81506: [PATCH] Extend w32 window events to expose IME composition string interface
Eli Zaretskii <[email protected]>
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
[Please always use Reply to All when replying, to keep the bug tracker CC'ed.] > From: dANiuu zHaO <[email protected]> > Date: Tue, 28 Jul 2026 23:56:48 +0800 > > Thanks for your review. Since this is my first time contributing code, there are indeed many areas where I can > improve. > > Let me first address the question about the purpose of the changes. The relevant bug report is: > > https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68339 > > Emacs on Windows already supports the IME window, but the IME preedit window does not scale with the font > size in the buffer. This report describes exactly this issue — when using Microsoft Pinyin IME to type Chinese > on Windows, the font size in the preedit window is too small to be legible. I also don't have a good approach > for using ImmSetCompositionFont to address this. So instead, I extended the WM_IME_COMPOSITION event > to obtain the composition string from CJK input methods. My idea is that after obtaining these strings, I can > pass them to Elisp to render using overlays, rather than relying on the IME's own window to draw them. This is > a new feature. > > This hook reads the composition string from the WM_IME_COMPOSITION event, and its sole purpose is this > use case. If this is for making the font of the IME window more like the size of the default font, then why not use ImmSetCompositionFont, as suggested by bug#68339? I know that I said there it was not possible, but I think I was wrong: using ImmGetCompositionFont, we could retrieve the LOGFONT structure for the font the IME window uses, and then modify just one member of the structure, lfHeight, by setting it to the negative of FRAME_FONT (f)->pixel_size, and call ImmSetCompositionFont. AFAIU, this should be done when we receive the WM_IME_STARTCOMPOSITION message, with the same context we use for calling ImmSetCompositionWindow. Can you try that? > Regarding whether there is an equivalent implementation on GNU/Linux and X — I honestly don't know. I do > most of my work on Windows, so I'm not familiar with that. I apologize for this. If we use this for setting the font of the IME window, then we are okay, because we already have a similar code in xfns.c for X. However, providing a hook is much more general than this, so this is one more reason not to go the hook way. > As for the discussion from a few days ago about supporting IME in terminal (-nw) sessions — that is a difficult > challenge. I think it heavily depends on whether the terminal itself handles IME input properly. I haven't even > looked at Microsoft's documentation on this topic yet. So I believe it is unrelated to our previous discussion. Understood. > Regarding the code comments and style — those oversights were my mistake, and I will fix them in the next > patch. > > The static buffer size limit is indeed too small. I will switch to using MAX_ALLOCA or a similar approach. > > > +/* Fixed buffer for receiving IME composition (preedit) string. > > + IME composition strings are typically short, so 64 characters > > + is sufficient for most cases. The buffer is sized to 2 * 64 > > + bytes because each wide character (wchar_t) occupies 2 bytes > > + under UTF-16 encoding on Windows. */ > > +static char composition_ime_buf[2 * 64]; > > For the wchar_t buffer allocation, multiplying by 4 when converting to UTF-8 would indeed be better. The IME > composition strings produced by the input method I personally use do not exceed 2 bytes when converted to > UTF-8, so I made that assumption and overlooked the fact that other CJK input methods may produce longer > strings. > > > + wlen = WideCharToMultiByte (CP_UTF8, 0, > > + wbuf, > > + size / sizeof (wchar_t), > > + composition_ime_buf, > > + sizeof (composition_ime_buf), > > + NULL, NULL); > > Regarding calling Lisp inside read_socket_hook — I also feel that calling Lisp there is somewhat inappropriate; > it is a bit slow. As for safety, I haven't encountered issues in my own local testing, but more testing is needed to > verify. So I would like to know: what is the recommended path within the project for notifying Lisp with data > obtained from window events? I will follow whatever the recommended approach is. > > > + case WM_IME_COMPOSITION: > > + { > > + int len = (int) msg.msg.lParam; > > + char *buf = (char *) msg.msg.wParam; > > + Lisp_Object str = make_string_from_utf8 (buf, len); > > + CALLN (Frun_hook_with_args, Qw32_ime_composition_hook, str); > > Regarding the review of w32-ime-preedit and w32-ime-composition-hook — you are right that w32-ime-preedit > is not needed. We can simply check whether w32-ime-composition-hook is nil. I didn't think of this at all when > writing it. I agree this is absolutely the right approach. > > Finally, thank you for your review. I plan to send a second patch in the next few days. I would like to get this > feature into Emacs — it will allow users on Windows to see the IME preedit window clearly without needing to > install a third-party input method package. Thanks.