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

Eli Zaretskii <[email protected]> Wed, 05 Aug 2026 18:47:55 +0300
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
> From: dANiuu zHaO <[email protected]>
> Date: Wed, 5 Aug 2026 22:40:23 +0800
> Cc: Eli Zaretskii <[email protected]>, [email protected]
> 
> 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.

One idea is to introduce a variable, probably exposed to Lisp, which
scales w32_system_caret_height down to a reasonable value, which is
similar to the scaled font used by the Emacs frame, and then use the
height of the caret multiplied by that scale variable as the height
for the IME font..

Another idea is to look at the code which updates
w32_system_caret_height when text-scaling changes, understand why the
caret is so large and implement in the same place the scaling of
lfHeight similar to what we do to scale w32_system_caret_height, but
in a way that produces a better size.

If none of this works, we could add to 'struct frame' a new member
that holds the height of the scaled default font, and then the input
thread could simply access the 'struct frame' of the selected frame
and use that value.

Does this make sense?