bug#68339: [patch] Set the IME window font to an appropriate size

dANiuu zHaO <[email protected]> Wed, 5 Aug 2026 22:40:23 +0800
Newsgroups gmane.emacs.bugs
Message-ID <CAEOE9jfKSQkZ4obY_jNzPUcLH4DE1i5BwQdXv38D4n2szK+yeg@mail.gmail.com>
Let me summarize the current progress.


The first patch — the core code is this:

> font = FRAME_FONT (f);
> GetObjectW (FONT_HANDLE (font), sizeof (lf), &lf);
> set_ime_composition_font_fn (context, &lf);

This code has no threading issues. However, when the font has been scaled,
the font height obtained by FRAME_FONT is not the scaled one, but the
default font height.
It lacks dynamic adjustment of lf.lfHeight. There is no thread-safety issue.


The third patch — the code is this:

> face = FACE_FROM_ID_OR_NULL (f, lookup_basic_face (w, f,
DEFAULT_FACE_ID));
> font = face ? face->font : FRAME_FONT (f);
> GetObjectW (FONT_HANDLE (font), sizeof (lf), &lf);
> set_ime_composition_font_fn (context, &lf);

Through lookup_basic_face, I can access the scaled font, and its height is
correct.
However, there are threading issues — it has a probability of triggering
the emacs_abort function.
My guess is that the cause is accessing it from within the Win32 message
loop.


The third patch — the code is this:

> font = FRAME_FONT (f);
> GetObjectW (FONT_HANDLE (font), sizeof (lf), &lf);
> lf.lfHeight = -w32_system_caret_height;
> set_ime_composition_font_fn (context, &lf);

It is the same as the first patch — no thread-safety issues.
However, it does have dynamic adjustment of lf.lfHeight,
which can be dynamically set based on the cursor height.
The problem is that w32_system_caret_height tends to be much larger than the
actual font pixel height — it is oversized.


> Does it not work even if you start the composition _after_ changing
> the font via the mouse-wheel?  If so, I think it's because FRAME_FONT
> gives you the default font, which doesn't take face-remapping (which
> is how text-scale works in Emacs) into account.  To get the font after
> remapping, you need to do something like:
>
>   . call lookup_basic_face (W, F, DEFAULT_FACE_ID), where W and F and
>     the window and the frame; this gives you a face ID
>   . use FACE_FROM_ID to get 'struct face' from the above ID
>   . obtain the font as face->font
>   . if any of that fails, use FRAME_FONT as you do now

I think I should listen to Eli and revert to the first patch for now.
I don't have any good ideas at the moment either.
It wouldn't be good if the changes get too complicated.

dANiuu zHaO <[email protected]> 于2026年8月5日周三 15:05写道:

> [PATCH 4] Set the IME window font to an appropriate size
>
> Already fixed. During my local testing, I found that lookup_basic_face
> would trigger an emacs_abort assertion — specifically, the function that
> triggered it was make_uninit_string. So instead, I changed it to read the
> global w32_system_caret_height as the lfHeight value, which is quite clever.
>
> Eason Huang <[email protected]> 于2026年8月5日周三 10:25写道:
>
>> dANiuu zHaO <[email protected]> writes:
>>
>> > [patch 3] Set the IME window font to an appropriate size
>> >
>> > Changed to use FACE_FROM_ID_OR_NULL and added a fallback check: if face
>> is NULL, use FRAME_FONT
>> > instead.
>> >
>> > dANiuu zHaO <[email protected]> 于2026年8月3日周一 00:10写道:
>> >
>> >  Yes, more testing is a good idea. I will share and distribute these
>> patches in the Emacs communities
>> >  I know, and I hope more people can help test them.
>> >
>> >  As for the code suggestions, I will send an improved patch shortly.
>> >
>> >  Finally, I have signed the form and am waiting for a response.
>> >  Thanks.
>> >
>> >  Eli Zaretskii <[email protected]> 于2026年8月2日周日 23:52写道:
>> >
>> >  > From: dANiuu zHaO <[email protected]>
>> >  > Date: Sun, 2 Aug 2026 23:27:31 +0800
>> >  > Cc: [email protected]
>> >  >
>> >  > You were right. I only needed to build it once locally and it worked
>> perfectly — exactly as
>> >  you described, with no
>> >  > errors at all. There's a new patch and a GIF attached to demonstrate
>> my current work.
>> >  > Everything works fine on my local machine, but it will likely need
>> more testing from others.
>> >  Lastly, thank you for
>> >  > your guidance — without it, it would have taken me much longer to
>> figure out the root cause.
>> >
>> >  Yes, more testing is a good idea.  Would people who have IME installed
>> >  on their Windows systems please apply the patch, try using IME, and
>> >  report back?
>> >
>> >  > Finally, I agree to sign the copyright-assignment agreement.
>> >
>> >  Thanks, form sent off-list.
>> >
>> >  > +       face = FACE_FROM_ID (f, lookup_basic_face (w, f,
>> DEFAULT_FACE_ID));
>> >  > +       GetObjectW (FONT_HANDLE (face->font), sizeof (lf), &lf);
>> >
>> >  Please add the fallback here, in case something goes wrong.
>> >  Specifically, if either 'face' or face->font is NULL, we should use
>> >  FRAME_FONT as fallback.
>> >
>> >  Also, please use FACE_FROM_ID_OR_NULL instead of FACE_FROM_ID, because
>> >  the latter will hit assert violation if the result is NULL, whereas we
>> >  want to handle that ourselves here.
>> >
>> >
>> Hello Eli and dANiuu,
>>
>> Thanks for implemented this nice feature.
>> I tested the latest patch, It works. But it will crash my Emacs when
>> variable-pitch-mode and global-display-line-numbers-mode is enabled.
>>
>> The version I build is emacs-31 branch
>> commit:d828a19fdc064b4fa324779143d78fbff9a9a7b2
>>
>> steps to reproduce:
>>
>> 1. start emacs with emacs -Q
>> 2. Past more example text into the * scratch * buffer
>> 3. Enable variable-pitch-mode and global-display-line-numbers-mode by M-x
>> 4. Use C-n or C-p navigate the text on buffer * scratch * will trigger
>> crash
>>
>> I recorded an video for this, you can get it by below link:
>>
>> Video link: https://pan.baidu.com/s/1RhIAY6HIxYpFXDSWeOfTaA
>> password: uxcg
>>
>> Hope that it can be helpful.
>>
>>
>> --
>> Eason Huang
>>
>>