The imm_thread_data, ime_update related code in WINE_IME_PROCESS_KEY should be moved into WINE_IME_TO_ASCII_EX.
Indeed it should, and the latest version does so now.
When STATUS_BUFFER_TOO_SMALL is returned, macdrv_ImeToAsciiEx should not be executed again.
This is fixed by having a separate WINE_IME_TO_ASCII_EX_USER call to interact with the user driver. I believe the other issues you noted are also fixed by this redesign, but feel free to correct me if I am wrong. This does have have the side-effect of always first processing input as IME and then backtracking for user drivers that do not implement ImeProcessKey for non-IME layouts, until something like https://gitlab.winehq.org/wine/wine/-/merge_requests/10138 is merged (and I think doing them is this order would also be better). After that the user driver ImeProcessKey, should be able to be removed... There are some technicalities left, like whether key up events should be processed in general to create the equivalent logic in win32u that is currently sitting in macdrv_ImeProcessKey. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9992#note_133864