In the Korean locale, wine uses the on-the-spot style.
export LC_ALL="ko_KR.UTF-8" wine64 notepad
In this case, the problem is that the preedit string is not displayed properly.
If XIM_COMMIT and XIM_PREEDIT_DRAW are sent from the input method, X11DRV_KeyEvent() is repeatedly executed in wine, and as a result, the order of commit string and preedit string is frequently changed. So, it often happens that the preedit string is not displayed when entering Korean.
Also, the X11DRV_MsgWaitForMultipleObjectsEx() function in evenc.c runs periodically at about 0.25 second intervals, even if there are no events. Therefore, there is a possibility that the process_events() is executed repeatedly for a certain event.
This patch prevents duplicate execution of X11DRV_KeyEvent() and X11DRV_MsgWaitForMultipleObjectsEx(). As a result, it prevents the order of commit string and preedit string from being reversed.
Signed-off-by: Hodong Kim hodong@nimfsoft.com --- dlls/winex11.drv/event.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 170111e9c28..d56b4fc2fde 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -80,6 +80,15 @@ extern BOOL ximInComposeMode; #define XEMBED_UNREGISTER_ACCELERATOR 13 #define XEMBED_ACTIVATE_ACCELERATOR 14
+static CRITICAL_SECTION event_section; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &event_section, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": event_section") } +}; +static CRITICAL_SECTION event_section = { &critsect_debug, -1, 0, 0, 0, 0 }; + Bool (*pXGetEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ) = NULL; void (*pXFreeEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ) = NULL;
@@ -407,10 +416,13 @@ static inline BOOL call_event_handler( Display *display, XEvent *event ) static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,XPointer), ULONG_PTR arg ) { XEvent event, prev_event; - int count = 0; - BOOL queued = FALSE; - enum event_merge_action action = MERGE_DISCARD; - + int count; + BOOL queued; + enum event_merge_action action; + EnterCriticalSection( &event_section ); + count = 0; + queued = FALSE; + action = MERGE_DISCARD; prev_event.type = 0; while (XCheckIfEvent( display, &event, filter, (char *)arg )) { @@ -445,6 +457,12 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X else continue; /* filtered, ignore it */ } + else if (event.type == KeyPress || event.type == KeyRelease) + { + BOOL ret = call_event_handler( display, &event ); + LeaveCriticalSection( &event_section ); + return ret; + } get_event_data( &event ); if (prev_event.type) action = merge_events( &prev_event, &event ); switch( action ) @@ -468,6 +486,7 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X free_event_data( &prev_event ); XFlush( gdi_display ); if (count) TRACE( "processed %d events, returning %d\n", count, queued ); + LeaveCriticalSection( &event_section ); return queued; }
@@ -521,7 +540,7 @@ DWORD EVENT_x11_time_to_win32_time(Time time) } else { - /* If we got an event in the 'future', then our clock is clearly wrong. + /* If we got an event in the 'future', then our clock is clearly wrong. If we got it more than 10000 ms in the future, then it's most likely that the clock has wrapped. */
@@ -728,7 +747,7 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event ) { XClientMessageEvent xev; xev = *event; - + TRACE("NET_WM Ping\n"); xev.window = DefaultRootWindow(xev.display); XSendEvent(xev.display, xev.window, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&xev); @@ -1445,7 +1464,7 @@ static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt ) RECT tempRect;
if (!IsWindowEnabled(hQueryWnd)) return 0; - + GetWindowRect(hQueryWnd, &tempRect);
if(!PtInRect(&tempRect, *lpPt)) return 0; @@ -1468,7 +1487,7 @@ static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt ) }
if(!(GetWindowLongA( hQueryWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return 0; - + ScreenToClient(hQueryWnd, lpPt);
return hQueryWnd;