Bug 466408 [OSX] First use of dead keys always shows incorrect behavior r=smichaud, sr=roc a191=b191
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 30 Dec 2008 23:16:27 +0900
changeset 22545 b97b7d5cd0677f32009928f22d27251c4150b7b7
parent 22544 8c8305008ebb37d403c01411e5d7334a8a02656b
child 22546 ec5aa616b2b45f62119220cf4d78ffd307e646ce
push id277
push usermasayuki@d-toybox.com
push dateTue, 30 Dec 2008 14:17:20 +0000
reviewerssmichaud, roc
bugs466408
milestone1.9.1b3pre
Bug 466408 [OSX] First use of dead keys always shows incorrect behavior r=smichaud, sr=roc a191=b191
widget/src/cocoa/nsChildView.mm
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -104,21 +104,23 @@ extern "C" {
   CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform);
   CG_EXTERN void CGContextResetClip(CGContextRef);
 }
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
 struct __TISInputSource;
 typedef __TISInputSource* TISInputSourceRef;
 #endif
+TISInputSourceRef (*Leopard_TISCopyCurrentKeyboardInputSource)() = NULL;
 TISInputSourceRef (*Leopard_TISCopyCurrentKeyboardLayoutInputSource)() = NULL;
 void* (*Leopard_TISGetInputSourceProperty)(TISInputSourceRef inputSource, CFStringRef propertyKey) = NULL;
 CFArrayRef (*Leopard_TISCreateInputSourceList)(CFDictionaryRef properties, Boolean includeAllInstalled) = NULL;
 CFStringRef kOurTISPropertyUnicodeKeyLayoutData = NULL;
 CFStringRef kOurTISPropertyInputSourceID = NULL;
+CFStringRef kOurTISPropertyInputSourceLanguages = NULL;
 
 extern PRBool gCocoaWindowMethodsSwizzled; // Defined in nsCocoaWindow.mm
 
 extern nsISupportsArray *gDraggedTransferables;
 
 PRBool nsTSMManager::sIsIMEEnabled = PR_TRUE;
 PRBool nsTSMManager::sIsRomanKeyboardsOnly = PR_FALSE;
 PRBool nsTSMManager::sIgnoreCommit = PR_FALSE;
@@ -509,21 +511,23 @@ nsChildView::nsChildView() : nsBaseWidge
   if (nsToolkit::OnLeopardOrLater() && !Leopard_TISCopyCurrentKeyboardLayoutInputSource) {
     // This libary would already be open for LMGetKbdType (and probably other
     // symbols), so merely using RTLD_DEFAULT in dlsym would be sufficient,
     // but man dlsym says: "all mach-o images in the process (except ...) are
     // searched in the order they were loaded.  This can be a costly search
     // and should be avoided."
     void* hitoolboxHandle = dlopen("/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/Versions/A/HIToolbox", RTLD_LAZY);
     if (hitoolboxHandle) {
+      *(void **)(&Leopard_TISCopyCurrentKeyboardInputSource) = dlsym(hitoolboxHandle, "TISCopyCurrentKeyboardInputSource");
       *(void **)(&Leopard_TISCopyCurrentKeyboardLayoutInputSource) = dlsym(hitoolboxHandle, "TISCopyCurrentKeyboardLayoutInputSource");
       *(void **)(&Leopard_TISGetInputSourceProperty) = dlsym(hitoolboxHandle, "TISGetInputSourceProperty");
       *(void **)(&Leopard_TISCreateInputSourceList) = dlsym(hitoolboxHandle, "TISCreateInputSourceList");
       kOurTISPropertyUnicodeKeyLayoutData = *static_cast<CFStringRef*>(dlsym(hitoolboxHandle, "kTISPropertyUnicodeKeyLayoutData"));
       kOurTISPropertyInputSourceID = *static_cast<CFStringRef*>(dlsym(hitoolboxHandle, "kTISPropertyInputSourceID"));
+      kOurTISPropertyInputSourceLanguages = *static_cast<CFStringRef*>(dlsym(hitoolboxHandle, "kTISPropertyInputSourceLanguages"));
     }
   }
 }
 
 
 nsChildView::~nsChildView()
 {
   // notify the children that we're gone
@@ -6537,16 +6541,45 @@ nsTSMManager::OnDestroyView(NSView<mozVi
 
 PRBool
 nsTSMManager::GetIMEOpenState()
 {
   return GetScriptManagerVariable(smKeyScript) != smRoman ? PR_TRUE : PR_FALSE;
 }
 
 
+static const NSString* GetCurrentIMELanguage()
+{
+  if (!nsToolkit::OnLeopardOrLater()) {
+    // XXX [[NSInputManager currentInputManager] language] doesn't work fine.
+    switch (::GetScriptManagerVariable(smKeyScript)) {
+      case smJapanese:
+        return @"ja";
+      default:
+        return nil;
+    }
+  }
+
+  NS_PRECONDITION(Leopard_TISCopyCurrentKeyboardInputSource,
+    "Leopard_TISCopyCurrentKeyboardInputSource is not initialized");
+  TISInputSourceRef inputSource = Leopard_TISCopyCurrentKeyboardInputSource();
+  if (!inputSource) {
+    NS_ERROR("Leopard_TISCopyCurrentKeyboardInputSource failed");
+    return nil;
+  }
+
+  NS_PRECONDITION(Leopard_TISGetInputSourceProperty,
+    "Leopard_TISGetInputSourceProperty is not initialized");
+  CFArrayRef langs = static_cast<CFArrayRef>(
+    Leopard_TISGetInputSourceProperty(inputSource,
+                                      kOurTISPropertyInputSourceLanguages));
+  return static_cast<const NSString*>(CFArrayGetValueAtIndex(langs, 0));
+}
+
+
 void
 nsTSMManager::InitTSMDocument(NSView<mozView>* aViewForCaret)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   sDocumentID = ::TSMGetActiveDocument();
   if (!sDocumentID)
     return;
@@ -6569,18 +6602,21 @@ nsTSMManager::InitTSMDocument(NSView<moz
 
   if (err == noErr && TSMLevel >= windowLevel)
     return;
   ::TSMSetDocumentProperty(sDocumentID, kTSMDocumentWindowLevelPropertyTag,
                            sizeof(windowLevel), &windowLevel);
 
   // ATOK (Japanese IME) updates the window level at activating,
   // we need to notify the change with this hack.
-  ::DeactivateTSMDocument(sDocumentID);
-  ::ActivateTSMDocument(sDocumentID);
+  const NSString* lang = ::GetCurrentIMELanguage();
+  if (lang && [lang isEqualToString:@"ja"]) {
+    ::DeactivateTSMDocument(sDocumentID);
+    ::ActivateTSMDocument(sDocumentID);
+  }
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 
 void
 nsTSMManager::StartComposing(NSView<mozView>* aComposingView)
 {