Bug 838001 IME management code should use root widget instead of the nearest widget of the PresContext r=smaug, a=akeybl
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 06 Feb 2013 22:27:48 +0900
changeset 127435 5406b540b9d7ecb89f396cb57b984cdfb6ac36df
parent 127434 1d3935c780c296399e70ee4699aa6aeb1b4f7f94
child 127436 8dcddddb6e1ad44865710e8af5e9c5ecb115f19d
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, akeybl
bugs838001
milestone20.0a2
Bug 838001 IME management code should use root widget instead of the nearest widget of the PresContext r=smaug, a=akeybl
content/events/src/TextComposition.cpp
content/events/src/nsIMEStateManager.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
--- a/content/events/src/TextComposition.cpp
+++ b/content/events/src/TextComposition.cpp
@@ -101,17 +101,17 @@ TextComposition::NotifyIME(widget::Notif
 TextComposition::CompositionEventDispatcher::CompositionEventDispatcher(
                                                nsPresContext* aPresContext,
                                                nsINode* aEventTarget,
                                                uint32_t aEventMessage,
                                                const nsAString& aData) :
   mPresContext(aPresContext), mEventTarget(aEventTarget),
   mEventMessage(aEventMessage), mData(aData)
 {
-  mWidget = mPresContext->GetNearestWidget();
+  mWidget = mPresContext->GetRootWidget();
 }
 
 NS_IMETHODIMP
 TextComposition::CompositionEventDispatcher::Run()
 {
   if (!mPresContext->GetPresShell() ||
       mPresContext->GetPresShell()->IsDestroying()) {
     return NS_OK; // cannot dispatch any events anymore
--- a/content/events/src/nsIMEStateManager.cpp
+++ b/content/events/src/nsIMEStateManager.cpp
@@ -122,17 +122,17 @@ nsIMEStateManager::OnDestroyPresContext(
     }
   }
 
   if (aPresContext != sPresContext)
     return NS_OK;
 
   DestroyTextStateManager();
 
-  nsCOMPtr<nsIWidget> widget = sPresContext->GetNearestWidget();
+  nsCOMPtr<nsIWidget> widget = sPresContext->GetRootWidget();
   if (widget) {
     IMEState newState = GetNewIMEState(sPresContext, nullptr);
     InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
                               InputContextAction::LOST_FOCUS);
     SetIMEState(newState, nullptr, widget, action);
   }
   NS_IF_RELEASE(sContent);
   sPresContext = nullptr;
@@ -152,17 +152,17 @@ nsIMEStateManager::OnRemoveContent(nsPre
 
     if (compositionInContent) {
       // Store the composition before accessing the native IME.
       TextComposition storedComposition = *compositionInContent;
       // Try resetting the native IME state.  Be aware, typically, this method
       // is called during the content being removed.  Then, the native
       // composition events which are caused by following APIs are ignored due
       // to unsafe to run script (in PresShell::HandleEvent()).
-      nsCOMPtr<nsIWidget> widget = aPresContext->GetNearestWidget();
+      nsCOMPtr<nsIWidget> widget = aPresContext->GetRootWidget();
       if (widget) {
         nsresult rv =
           storedComposition.NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
         if (NS_FAILED(rv)) {
           storedComposition.NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
         }
         // By calling the APIs, the composition may have been finished normally.
         compositionInContent =
@@ -182,17 +182,17 @@ nsIMEStateManager::OnRemoveContent(nsPre
   if (!sPresContext || !sContent ||
       !nsContentUtils::ContentIsDescendantOf(sContent, aContent)) {
     return NS_OK;
   }
 
   DestroyTextStateManager();
 
   // Current IME transaction should commit
-  nsCOMPtr<nsIWidget> widget = sPresContext->GetNearestWidget();
+  nsCOMPtr<nsIWidget> widget = sPresContext->GetRootWidget();
   if (widget) {
     IMEState newState = GetNewIMEState(sPresContext, nullptr);
     InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
                               InputContextAction::LOST_FOCUS);
     SetIMEState(newState, nullptr, widget, action);
   }
 
   NS_IF_RELEASE(sContent);
@@ -214,17 +214,17 @@ nsresult
 nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
                                          nsIContent* aContent,
                                          InputContextAction aAction)
 {
   bool focusActuallyChanging =
     (sContent != aContent || sPresContext != aPresContext);
 
   nsCOMPtr<nsIWidget> oldWidget =
-    sPresContext ? sPresContext->GetNearestWidget() : nullptr;
+    sPresContext ? sPresContext->GetRootWidget() : nullptr;
   if (oldWidget && focusActuallyChanging) {
     // If we're deactivating, we shouldn't commit composition forcibly because
     // the user may want to continue the composition.
     if (aPresContext) {
       NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget);
     }
   }
 
@@ -234,17 +234,17 @@ nsIMEStateManager::OnChangeFocusInternal
   }
 
   if (!aPresContext) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIWidget> widget =
     (sPresContext == aPresContext) ? oldWidget.get() :
-                                     aPresContext->GetNearestWidget();
+                                     aPresContext->GetRootWidget();
   if (!widget) {
     return NS_OK;
   }
 
   // Handle secure input mode for password field input.
   bool contentIsPassword = false;
   if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML) {
     if (aContent->Tag() == nsGkAtoms::input) {
@@ -321,17 +321,17 @@ void
 nsIMEStateManager::OnClickInEditor(nsPresContext* aPresContext,
                                    nsIContent* aContent,
                                    nsIDOMMouseEvent* aMouseEvent)
 {
   if (sPresContext != aPresContext || sContent != aContent) {
     return;
   }
 
-  nsCOMPtr<nsIWidget> widget = aPresContext->GetNearestWidget();
+  nsCOMPtr<nsIWidget> widget = aPresContext->GetRootWidget();
   NS_ENSURE_TRUE_VOID(widget);
 
   bool isTrusted;
   nsresult rv = aMouseEvent->GetIsTrusted(&isTrusted);
   NS_ENSURE_SUCCESS_VOID(rv);
   if (!isTrusted) {
     return; // ignore untrusted event.
   }
@@ -379,17 +379,17 @@ nsIMEStateManager::OnFocusInEditor(nsPre
 void
 nsIMEStateManager::UpdateIMEState(const IMEState &aNewIMEState,
                                   nsIContent* aContent)
 {
   if (!sPresContext) {
     NS_WARNING("ISM doesn't know which editor has focus");
     return;
   }
-  nsCOMPtr<nsIWidget> widget = sPresContext->GetNearestWidget();
+  nsCOMPtr<nsIWidget> widget = sPresContext->GetRootWidget();
   if (!widget) {
     NS_WARNING("focused widget is not found");
     return;
   }
 
   // If the nsTextStateManager instance isn't managing the editor's current
   // editable root content, the editor frame might be reframed.  We should
   // recreate the instance at that time.
@@ -678,17 +678,17 @@ nsIMEStateManager::NotifyIME(Notificatio
 
 // static
 nsresult
 nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
                              nsPresContext* aPresContext)
 {
   NS_ENSURE_TRUE(aPresContext, NS_ERROR_INVALID_ARG);
 
-  nsIWidget* widget = aPresContext->GetNearestWidget();
+  nsIWidget* widget = aPresContext->GetRootWidget();
   if (!widget) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   return NotifyIME(aNotification, widget);
 }
 
 void
 nsTextStateManager::Init(nsIWidget* aWidget,
@@ -1088,17 +1088,17 @@ void
 nsIMEStateManager::CreateTextStateManager()
 {
   if (sTextStateObserver) {
     NS_WARNING("text state observer has been there already");
     MOZ_ASSERT(sTextStateObserver->IsManaging(sPresContext, sContent));
     return;
   }
 
-  nsCOMPtr<nsIWidget> widget = sPresContext->GetNearestWidget();
+  nsCOMPtr<nsIWidget> widget = sPresContext->GetRootWidget();
   if (!widget) {
     return; // Sometimes, there are no widgets.
   }
 
   // If it's not text ediable, we don't need to create nsTextStateManager.
   if (!IsEditableIMEState(widget)) {
     return;
   }
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1181,16 +1181,29 @@ nsIWidget*
 nsPresContext::GetNearestWidget(nsPoint* aOffset)
 {
   NS_ENSURE_TRUE(mShell, nullptr);
   nsIFrame* frame = mShell->GetRootFrame();
   NS_ENSURE_TRUE(frame, nullptr);
   return frame->GetView()->GetNearestWidget(aOffset);
 }
 
+nsIWidget*
+nsPresContext::GetRootWidget()
+{
+  NS_ENSURE_TRUE(mShell, nullptr);
+  nsViewManager* vm = mShell->GetViewManager();
+  if (!vm) {
+    return nullptr;
+  }
+  nsCOMPtr<nsIWidget> widget;
+  vm->GetRootWidget(getter_AddRefs(widget));
+  return widget.get();
+}
+
 // We may want to replace this with something faster, maybe caching the root prescontext
 nsRootPresContext*
 nsPresContext::GetRootPresContext()
 {
   nsPresContext* pc = this;
   for (;;) {
     nsPresContext* parent = pc->GetParentPresContext();
     if (!parent)
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -208,16 +208,22 @@ public:
    * @param aOffset     If non-null the offset from the origin of the root
    *                    frame's view to the widget's origin (usually positive)
    *                    expressed in appunits of this will be returned in
    *                    aOffset.
    */
   nsIWidget* GetNearestWidget(nsPoint* aOffset = nullptr);
 
   /**
+   * Returns the root widget for this.
+   * Note that the widget is a mediater with IME.
+   */
+  nsIWidget* GetRootWidget();
+
+  /**
    * Return the presentation context for the root of the view manager
    * hierarchy that contains this presentation context, or nullptr if it can't
    * be found (e.g. it's detached).
    */
   nsRootPresContext* GetRootPresContext();
   nsRootPresContext* GetDisplayRootPresContext();
   virtual bool IsRoot() { return false; }