winex11.drv: Remember last window that had the XIC focus and use it in ToUnicode() to make dead keys work more reliably.

Dmitry Timoshkov dmitry at codeweavers.com
Tue Jul 20 08:25:36 CDT 2010


The problem is that between KeyPress event and ToUnicode() call the window
which has got the event may change, or our heuristics to restore window in
the event structure may not restore exactly the same window, and XIC should
be exactly the same to work for dead keys.
---
 dlls/winex11.drv/keyboard.c |   10 +++++++---
 dlls/winex11.drv/window.c   |    6 +++++-
 dlls/winex11.drv/x11drv.h   |    1 +
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index d9da4d2..cabd82a 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -2541,9 +2541,13 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
     e.state = 0;
     e.type = KeyPress;
 
-    focus = GetFocus();
-    if (focus) focus = GetAncestor( focus, GA_ROOT );
-    if (!focus) focus = GetActiveWindow();
+    focus = x11drv_thread_data()->last_xic_hwnd;
+    if (!focus)
+    {
+        HWND focus = GetFocus();
+        if (focus) focus = GetAncestor( focus, GA_ROOT );
+        if (!focus) focus = GetActiveWindow();
+    }
     e.window = X11DRV_get_whole_window( focus );
     xic = X11DRV_get_ic( focus );
 
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index eb6432e..0bfd844 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1862,6 +1862,7 @@ void CDECL X11DRV_DestroyWindow( HWND hwnd )
     }
 
     if (thread_data->last_focus == hwnd) thread_data->last_focus = 0;
+    if (thread_data->last_xic_hwnd == hwnd) thread_data->last_xic_hwnd = 0;
     if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap );
     if (data->hWMIconMask) DeleteObject( data->hWMIconMask);
     wine_tsx11_lock();
@@ -2080,9 +2081,12 @@ XIC X11DRV_get_ic( HWND hwnd )
     XIM xim;
 
     if (!data) return 0;
+
+    x11drv_thread_data()->last_xic_hwnd = hwnd;
     if (data->xic) return data->xic;
     if (!(xim = x11drv_thread_data()->xim)) return 0;
-    return X11DRV_CreateIC( xim, data );
+    X11DRV_CreateIC( xim, data );
+    return data->xic;
 }
 
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 1cd610d..0e82a65 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -549,6 +549,7 @@ struct x11drv_thread_data
     Window   grab_window;          /* window that currently grabs the mouse */
     HWND     last_focus;           /* last window that had focus */
     XIM      xim;                  /* input method */
+    HWND     last_xic_hwnd;        /* last xic window */
     XFontSet font_set;             /* international text drawing font set */
     Window   selection_wnd;        /* window used for selection interactions */
     HKL      kbd_layout;           /* active keyboard layout */
-- 
1.7.0.6




More information about the wine-patches mailing list