Ken Thomases : winemac: Ignore spurious or redundant notifications that the keyboard input source changed.

Alexandre Julliard julliard at winehq.org
Tue May 16 16:05:10 CDT 2017


Module: wine
Branch: master
Commit: feb19ee6695c358313190115498fb4d78d26193d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=feb19ee6695c358313190115498fb4d78d26193d

Author: Ken Thomases <ken at codeweavers.com>
Date:   Mon May 15 17:17:47 2017 -0500

winemac: Ignore spurious or redundant notifications that the keyboard input source changed.

In particular, when an input method for an Asian language (e.g. Pinyin) is
selected, we were getting repeated notifications.  Querying the selected input
method upon receiving them suggested that the keyboard layout changed to U.S.
then back to Pinyin, then several redundant notifications with no apparent
change.

Since the handler for the posted KEYBOARD_CHANGED events sends WM_CANCELMODE to
the active window, this was having bad effects.

The spurious notifications can be distinguished by there being no current
text input context or client.  To detect redundant notifications, we track the
last keyboard input source and keyboard layout input source and compare with
the new ones to see if they really changed.

Signed-off-by: Ken Thomases <ken at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winemac.drv/cocoa_app.h |  2 ++
 dlls/winemac.drv/cocoa_app.m | 49 +++++++++++++++++++++++++++++++++++++-------
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h
index 1ca0bd7..e76a47c 100644
--- a/dlls/winemac.drv/cocoa_app.h
+++ b/dlls/winemac.drv/cocoa_app.h
@@ -50,6 +50,8 @@ enum {
     NSMutableSet* triedWindows;
     unsigned long windowFocusSerial;
 
+    TISInputSourceRef lastKeyboardInputSource;
+    TISInputSourceRef lastKeyboardLayoutInputSource;
     CGEventSourceKeyboardType keyboardType;
     NSEvent* lastFlagsChanged;
     BOOL inputSourceIsInputMethod;
diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m
index 2325654..77be095 100644
--- a/dlls/winemac.drv/cocoa_app.m
+++ b/dlls/winemac.drv/cocoa_app.m
@@ -413,13 +413,45 @@ static NSString* WineLocalizedString(unsigned int stringID)
         }
     }
 
-    - (void) keyboardSelectionDidChange
+    static BOOL EqualInputSource(TISInputSourceRef source1, TISInputSourceRef source2)
     {
-        TISInputSourceRef inputSourceLayout;
+        if (!source1 && !source2)
+            return TRUE;
+        if (!source1 || !source2)
+            return FALSE;
+        return CFEqual(source1, source2);
+    }
 
-        inputSourceIsInputMethodValid = FALSE;
+    - (void) keyboardSelectionDidChange:(BOOL)force
+    {
+        TISInputSourceRef inputSource, inputSourceLayout;
+
+        if (!force)
+        {
+            NSTextInputContext* context = [NSTextInputContext currentInputContext];
+            if (!context || ![context client])
+                return;
+        }
 
+        inputSource = TISCopyCurrentKeyboardInputSource();
         inputSourceLayout = TISCopyCurrentKeyboardLayoutInputSource();
+        if (!force && EqualInputSource(inputSource, lastKeyboardInputSource) &&
+            EqualInputSource(inputSourceLayout, lastKeyboardLayoutInputSource))
+        {
+            if (inputSource) CFRelease(inputSource);
+            if (inputSourceLayout) CFRelease(inputSourceLayout);
+            return;
+        }
+
+        if (lastKeyboardInputSource)
+            CFRelease(lastKeyboardInputSource);
+        lastKeyboardInputSource = inputSource;
+        if (lastKeyboardLayoutInputSource)
+            CFRelease(lastKeyboardLayoutInputSource);
+        lastKeyboardLayoutInputSource = inputSourceLayout;
+
+        inputSourceIsInputMethodValid = FALSE;
+
         if (inputSourceLayout)
         {
             CFDataRef uchr;
@@ -434,7 +466,7 @@ static NSString* WineLocalizedString(unsigned int stringID)
                 event->keyboard_changed.keyboard_type = self.keyboardType;
                 event->keyboard_changed.iso_keyboard = (KBGetLayoutType(self.keyboardType) == kKeyboardISO);
                 event->keyboard_changed.uchr = CFDataCreateCopy(NULL, uchr);
-                event->keyboard_changed.input_source = TISCopyCurrentKeyboardInputSource();
+                event->keyboard_changed.input_source = (TISInputSourceRef)CFRetain(inputSource);
 
                 if (event->keyboard_changed.uchr)
                 {
@@ -448,17 +480,20 @@ static NSString* WineLocalizedString(unsigned int stringID)
 
                 macdrv_release_event(event);
             }
-
-            CFRelease(inputSourceLayout);
         }
     }
 
+    - (void) keyboardSelectionDidChange
+    {
+        [self keyboardSelectionDidChange:NO];
+    }
+
     - (void) setKeyboardType:(CGEventSourceKeyboardType)newType
     {
         if (newType != keyboardType)
         {
             keyboardType = newType;
-            [self keyboardSelectionDidChange];
+            [self keyboardSelectionDidChange:YES];
         }
     }
 




More information about the wine-cvs mailing list