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

dANiuu zHaO <[email protected]> Thu, 6 Aug 2026 00:00:12 +0800
Newsgroups gmane.emacs.bugs
Message-ID <CAEOE9jdkDE=LRkhwQ-zEn2Rd+Lfx1jNqBod0dj+FNnkPS5rzDQ@mail.gmail.com>
I'll try everything I can.
The only remaining issue is the lfHeight value. Once that's resolved, it'll
be perfect.

Eli Zaretskii <[email protected]> 于 2026年8月5日周三 23:47写道:

> > 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?
>