Bug 1119133 Implement TextEventDispatcher::EndInputTransaction() for ensuring TextEventDispatcher forgets the link with TextInputProcessor r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 11 Jun 2015 12:53:42 +0900
changeset 280586 76a74dc6ccc9555294a8918e23101577502fc099
parent 280585 2bf42a83d15f0c80e85b75cb3e44f65c5ea9f0a2
child 280587 6e36d0a459997873cf57c015ca1b99c448eebf03
push id897
push userjlund@mozilla.com
push dateMon, 14 Sep 2015 18:56:12 +0000
treeherdermozilla-release@9411e2d2b214 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1119133
milestone41.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 1119133 Implement TextEventDispatcher::EndInputTransaction() for ensuring TextEventDispatcher forgets the link with TextInputProcessor r=smaug
dom/base/TextInputProcessor.cpp
widget/TextEventDispatcher.cpp
widget/TextEventDispatcher.h
--- a/dom/base/TextInputProcessor.cpp
+++ b/dom/base/TextInputProcessor.cpp
@@ -181,17 +181,24 @@ TextInputProcessor::BeginInputTransactio
   // dispatching an event, it'll fail to steal its ownership.  Then, we should
   // not throw an exception, just return false.
   if (dispatcher->IsComposing() || dispatcher->IsDispatchingEvent()) {
     return NS_OK;
   }
 
   // This instance has finished preparing to link to the dispatcher.  Therefore,
   // let's forget the old dispatcher and purpose.
-  UnlinkFromTextEventDispatcher();
+  if (mDispatcher) {
+    mDispatcher->EndInputTransaction(this);
+    if (NS_WARN_IF(mDispatcher)) {
+      // Forcibly initialize the members if we failed to end the input
+      // transaction.
+      UnlinkFromTextEventDispatcher();
+    }
+  }
 
   if (aForTests) {
     rv = dispatcher->BeginInputTransactionForTests(this);
   } else {
     rv = dispatcher->BeginInputTransaction(this);
   }
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/widget/TextEventDispatcher.cpp
+++ b/widget/TextEventDispatcher.cpp
@@ -79,16 +79,36 @@ TextEventDispatcher::BeginInputTransacti
   mForTests = aForTests;
   if (listener && listener != aListener) {
     listener->OnRemovedFrom(this);
   }
   return NS_OK;
 }
 
 void
+TextEventDispatcher::EndInputTransaction(TextEventDispatcherListener* aListener)
+{
+  if (NS_WARN_IF(IsComposing()) || NS_WARN_IF(IsDispatchingEvent())) {
+    return;
+  }
+
+  nsCOMPtr<TextEventDispatcherListener> listener = do_QueryReferent(mListener);
+  if (NS_WARN_IF(!listener)) {
+    return;
+  }
+
+  if (NS_WARN_IF(listener != aListener)) {
+    return;
+  }
+
+  mListener = nullptr;
+  listener->OnRemovedFrom(this);
+}
+
+void
 TextEventDispatcher::OnDestroyWidget()
 {
   mWidget = nullptr;
   mPendingComposition.Clear();
   nsCOMPtr<TextEventDispatcherListener> listener = do_QueryReferent(mListener);
   mListener = nullptr;
   if (listener) {
     listener->OnRemovedFrom(this);
--- a/widget/TextEventDispatcher.h
+++ b/widget/TextEventDispatcher.h
@@ -55,16 +55,24 @@ public:
    *                              TextEventDispatcher.  See mListener
    *                              definition below.
    */
   nsresult BeginInputTransaction(TextEventDispatcherListener* aListener);
   nsresult BeginInputTransactionForTests(
              TextEventDispatcherListener* aListener);
 
   /**
+   * EndInputTransaction() should be called when the listener stops using
+   * the TextEventDispatcher.
+   *
+   * @param aListener       The listener using the TextEventDispatcher instance.
+   */
+  void EndInputTransaction(TextEventDispatcherListener* aListener);
+
+  /**
    * OnDestroyWidget() is called when mWidget is being destroyed.
    */
   void OnDestroyWidget();
 
   /**
    * GetState() returns current state of this class.
    *
    * @return        NS_OK: Fine to compose text.