Bug 875674 part.3 Implement windowLevel of NSTextInputClient r=smichaud
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 11 Jul 2013 16:46:35 +0900
changeset 138087 4b4ecd2243660f3314dc6f2652e74ced565142d3
parent 138086 680e0bd7f71f918e98d14540646d3ad9a9d62ff1
child 138088 9fd6977113ae1cf030c334dda60232bfaf19976e
push id30823
push usermasayuki@d-toybox.com
push dateThu, 11 Jul 2013 07:47:10 +0000
treeherdermozilla-inbound@86a041d63d65 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmichaud
bugs875674
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 875674 part.3 Implement windowLevel of NSTextInputClient r=smichaud
widget/cocoa/TextInputHandler.h
widget/cocoa/TextInputHandler.mm
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
--- a/widget/cocoa/TextInputHandler.h
+++ b/widget/cocoa/TextInputHandler.h
@@ -364,16 +364,23 @@ public:
    */
   nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
                                     int32_t aNativeKeyCode,
                                     uint32_t aModifierFlags,
                                     const nsAString& aCharacters,
                                     const nsAString& aUnmodifiedCharacters);
 
   /**
+   * GetWindowLevel() returns the window level of current focused (in Gecko)
+   * window.  E.g., if an <input> element in XUL panel has focus, this returns
+   * the XUL panel's window level.
+   */
+  NSInteger GetWindowLevel();
+
+  /**
    * IsSpecialGeckoKey() checks whether aNativeKeyCode is mapped to a special
    * Gecko keyCode.  A key is "special" if it isn't used for text input.
    *
    * @param aNativeKeyCode        A native keycode.
    * @return                      If the keycode is mapped to a special key,
    *                              TRUE.  Otherwise, FALSE.
    */
   static bool IsSpecialGeckoKey(UInt32 aNativeKeyCode);
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -2261,33 +2261,20 @@ IMEInputHandler::ResetIMEWindowLevel()
   if (!doc) {
     // retry
     mPendingMethods |= kResetIMEWindowLevel;
     NS_WARNING("Application is active but there is no active document");
     ResetTimer();
     return;
   }
 
-  // When the focus of Gecko is on a text box of a popup panel, the actual
-  // focused view is the panel's parent view (mView). But the editor is
-  // displayed on the popuped widget's view (editorView).  So, their window
-  // level may be different.
-  NSView<mozView>* editorView = mWidget->GetEditorView();
-  if (!editorView) {
-    NS_ERROR("editorView is null");
-    return;
-  }
-
   // We need to set the focused window level to TSMDocument. Then, the popup
   // windows of IME (E.g., a candidate list window) will be over the focused
   // view. See http://developer.apple.com/technotes/tn2005/tn2128.html#TNTAG1
-  NSInteger windowLevel = [[editorView window] level];
-  PR_LOG(gLog, PR_LOG_ALWAYS,
-    ("%p IMEInputHandler::ResetIMEWindowLevel, windowLevel=%s (%X)",
-     this, GetWindowLevelName(windowLevel), windowLevel));
+  NSInteger windowLevel = GetWindowLevel();
 
   // Chinese IMEs on 10.5 don't work fine if the level is NSNormalWindowLevel,
   // then, we need to increment the value.
   if (windowLevel == NSNormalWindowLevel)
     windowLevel++;
 
   ::TSMSetDocumentProperty(GetCurrentTSMDocumentID(),
                            kTSMDocumentWindowLevelPropertyTag,
@@ -4128,16 +4115,45 @@ TextInputHandlerBase::SynthesizeNativeKe
     mKeyboardOverride = currentLayout;
   }
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
+NSInteger
+TextInputHandlerBase::GetWindowLevel()
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+  PR_LOG(gLog, PR_LOG_ALWAYS,
+    ("%p TextInputHandlerBase::GetWindowLevel, Destryoed()=%s",
+     this, TrueOrFalse(Destroyed())));
+
+  if (Destroyed()) {
+    return NSNormalWindowLevel;
+  }
+
+  // When an <input> element on a XUL <panel> is focused, the actual focused view
+  // is the panel's parent view (mView). But the editor is displayed on the
+  // popped-up widget's view (editorView).  We want the latter's window level.
+  NSView<mozView>* editorView = mWidget->GetEditorView();
+  NS_ENSURE_TRUE(editorView, NSNormalWindowLevel);
+  NSInteger windowLevel = [[editorView window] level];
+
+  PR_LOG(gLog, PR_LOG_ALWAYS,
+    ("%p TextInputHandlerBase::GetWindowLevel, windowLevel=%s (%X)",
+     this, GetWindowLevelName(windowLevel), windowLevel));
+
+  return windowLevel;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NSNormalWindowLevel);
+}
+
 /* static */ bool
 TextInputHandlerBase::IsPrintableChar(PRUnichar aChar)
 {
   return (aChar >= 0x20 && aChar <= 0x7E) || aChar >= 0xA0;
 }
 
 
 /* static */ bool
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -210,17 +210,17 @@ typedef NSInteger NSEventGestureAxis;
 // Lion and above
 - (NSEventPhase)momentumPhase;
 @end
 
 @interface ChildView : NSView<
 #ifdef ACCESSIBILITY
                               mozAccessible,
 #endif
-                              mozView, NSTextInput>
+                              mozView, NSTextInput, NSTextInputClient>
 {
 @private
   // the nsChildView that created the view. It retains this NSView, so
   // the link back to it must be weak.
   nsChildView* mGeckoChild;
 
   // Text input handler for mGeckoChild and us.  Note that this is a weak
   // reference.  Ideally, this should be a strong reference but a ChildView
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -5088,16 +5088,29 @@ static int32_t RoundUp(double aDouble)
 
   NS_ENSURE_TRUE(mTextInputHandler, [NSArray array]);
   return mTextInputHandler->GetValidAttributesForMarkedText();
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 #pragma mark -
+// NSTextInputClient implementation
+
+- (NSInteger)windowLevel
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+  NS_ENSURE_TRUE(mTextInputHandler, [[self window] level]);
+  return mTextInputHandler->GetWindowLevel();
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NSNormalWindowLevel);
+}
+
+#pragma mark -
 
 #ifdef __LP64__
 - (NSTextInputContext *)inputContext
 {
   if (mIsPluginView && mPluginEventModel == NPEventModelCocoa)
     return [[ComplexTextInputPanel sharedComplexTextInputPanel] inputContext];
   else
     return [super inputContext];