From 95a64cbdd2dab47c38cb3be48a753e9213e7be15 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Wed, 22 Feb 2023 08:35:55 +0900 Subject: [PATCH] [NTUSER] Send WM_IME_SYSTEM:IMS_UPDATEIMEUI (#5075) Send WM_IME_SYSTEM:IMS_UPDATEIMEUI message after window position change to improve IME UI sync. CORE-11700, CORE-15289 --- win32ss/user/ntuser/winpos.c | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/win32ss/user/ntuser/winpos.c b/win32ss/user/ntuser/winpos.c index ba4d451de93..45c721de368 100644 --- a/win32ss/user/ntuser/winpos.c +++ b/win32ss/user/ntuser/winpos.c @@ -4,9 +4,11 @@ * PURPOSE: Windows * FILE: win32ss/user/ntuser/winpos.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) */ #include +#include DBG_DEFAULT_CHANNEL(UserWinpos); /* GLOBALS *******************************************************************/ @@ -1743,6 +1745,43 @@ ForceNCPaintErase(PWND Wnd, HRGN hRgn, PREGION pRgn) } } +static VOID FASTCALL IntImeWindowPosChanged(VOID) +{ + HWND *phwnd; + PWND pwndNode, pwndDesktop = UserGetDesktopWindow(); + PWINDOWLIST pWL; + USER_REFERENCE_ENTRY Ref; + + if (!pwndDesktop) + return; + + /* Enumerate the windows to get the IME windows (of default and non-default) */ + pWL = IntBuildHwndList(pwndDesktop->spwndChild, IACE_LIST, gptiCurrent); + if (!pWL) + return; + + for (phwnd = pWL->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd) + { + if (gptiCurrent->TIF_flags & TIF_INCLEANUP) + break; + + pwndNode = ValidateHwndNoErr(*phwnd); + if (pwndNode == NULL || + pwndNode->head.pti != gptiCurrent || + pwndNode->pcls->atomClassName != gpsi->atomSysClass[ICLS_IME]) + { + continue; + } + + /* Now hwndNode is an IME window of the current thread */ + UserRefObjectCo(pwndNode, &Ref); + co_IntSendMessage(*phwnd, WM_IME_SYSTEM, IMS_UPDATEIMEUI, 0); + UserDerefObjectCo(pwndNode); + } + + IntFreeHwndList(pWL); +} + /* x and y are always screen relative */ BOOLEAN FASTCALL co_WinPosSetWindowPos( @@ -2303,6 +2342,13 @@ co_WinPosSetWindowPos( IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); } + /* Send WM_IME_SYSTEM:IMS_UPDATEIMEUI to the IME windows if necessary */ + if ((WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)) + { + if (IS_IMM_MODE()) + IntImeWindowPosChanged(); + } + if(bPointerInWindow != IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y)) { /* Generate mouse move message */ @@ -3165,6 +3211,7 @@ BOOL FASTCALL IntEndDeferWindowPosEx(HDWP hdwp, BOOL bAsync) UserDerefObjectCo(pwnd); } + ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP); UserDereferenceObject(pDWP); UserDeleteObject(hdwp, TYPE_SETWINDOWPOS);