Bug 1077345 part.13 nsGtkIMModule should use NS_COMPOSITION_COMMIT* event r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 25 Nov 2014 14:02:34 +0900
changeset 241640 4631a7474d8a15d4f645861660b0c61579e2a37a
parent 241639 a724c487bebc768a358c89fc817f23908c2ae7dd
child 241655 f3e841fb7358e9dc029dc7b3a575a7a2109aaf36
child 241749 9e4f24936bbac8d16af587d44e0ebb8daff8f970
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1077345
milestone36.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 1077345 part.13 nsGtkIMModule should use NS_COMPOSITION_COMMIT* event r=m_kato
widget/gtk/nsGtkIMModule.cpp
widget/gtk/nsGtkIMModule.h
--- a/widget/gtk/nsGtkIMModule.cpp
+++ b/widget/gtk/nsGtkIMModule.cpp
@@ -364,18 +364,17 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCal
             } else {
                 // A Hangul input engine for SCIM doesn't emit preedit_end
                 // signal even when composition string becomes empty.  On the
                 // other hand, we should allow to make composition with empty
                 // string for other languages because there *might* be such
                 // IM.  For compromising this issue, we should dispatch
                 // compositionend event, however, we don't need to reset IM
                 // actually.
-                DispatchCompositionEventsForCommit(activeContext,
-                                                   EmptyString());
+                DispatchCompositionCommitEvent(activeContext, &EmptyString());
                 filterThisEvent = false;
             }
         } else {
             // Key release event may not be consumed by IM, however, we
             // shouldn't dispatch any keyup event during composition.
             filterThisEvent = true;
         }
     }
@@ -744,17 +743,17 @@ nsGtkIMModule::OnEndCompositionNative(Gt
     mComposingContext = nullptr;
 
     if (!IsComposing()) {
         // If we already handled the commit event, we should do nothing here.
         return;
     }
 
     // Be aware, widget can be gone
-    DispatchCompositionEventsForCommit(aContext, mDispatchedCompositionString);
+    DispatchCompositionCommitEvent(aContext);
 }
 
 /* static */
 void
 nsGtkIMModule::OnChangeCompositionCallback(GtkIMContext *aContext,
                                            nsGtkIMModule* aModule)
 {
     aModule->OnChangeCompositionNative(aContext);
@@ -916,17 +915,17 @@ nsGtkIMModule::OnCommitCompositionNative
                  this));
             mFilterKeyEvent = false;
             return;
         }
     }
 
     NS_ConvertUTF8toUTF16 str(commitString);
     // Be aware, widget can be gone
-    DispatchCompositionEventsForCommit(aContext, str);
+    DispatchCompositionCommitEvent(aContext, &str);
 }
 
 void
 nsGtkIMModule::GetCompositionString(GtkIMContext* aContext,
                                     nsAString& aCompositionString)
 {
     gchar *preedit_string;
     gint cursor_pos;
@@ -1091,98 +1090,71 @@ nsGtkIMModule::DispatchCompositionChange
     // DispatchEvent is async on e10s, so composition rect isn't updated now
     // on tab parent.
     mCompositionTargetOffset = targetOffset;
 
     return true;
 }
 
 bool
-nsGtkIMModule::DispatchCompositionEventsForCommit(
+nsGtkIMModule::DispatchCompositionCommitEvent(
                    GtkIMContext* aContext,
-                   const nsAString& aCommitString)
+                   const nsAString* aCommitString)
 {
     PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
-        ("GtkIMModule(%p): DispatchCompositionEventsForCommit, aContext=%p, "
-         "aCommitString=\"%s\"",
-         this, aContext, NS_ConvertUTF16toUTF8(aCommitString).get()));
+        ("GtkIMModule(%p): DispatchCompositionCommitEvent, aContext=%p, "
+         "aCommitString=%p, (\"%s\")",
+         this, aContext, aCommitString,
+         aCommitString ? NS_ConvertUTF16toUTF8(*aCommitString).get() : ""));
 
     if (!mLastFocusedWindow) {
         PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
             ("    FAILED, there are no focused window in this module"));
         return false;
     }
 
     if (!IsComposing()) {
-        if (aCommitString.IsEmpty()) {
+        if (!aCommitString || aCommitString->IsEmpty()) {
             PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
                 ("    FAILED, there is no composition and empty commit "
                  "string"));
             return true;
         }
         PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
             ("    The composition wasn't started, force starting..."));
         nsCOMPtr<nsIWidget> kungFuDeathGrip(mLastFocusedWindow);
         if (!DispatchCompositionStart(aContext)) {
             return false;
         }
     }
 
     nsRefPtr<nsWindow> lastFocusedWindow(mLastFocusedWindow);
 
-    // First, dispatch a compositionchange event for committing with
-    // aCommitString.
-    mCompositionState =
-        eCompositionState_CommitCompositionChangeEventDispatched;
-
-    WidgetCompositionEvent compositionChangeEvent(true, NS_COMPOSITION_CHANGE,
-                                                  mLastFocusedWindow);
-    InitEvent(compositionChangeEvent);
-    compositionChangeEvent.mData = aCommitString;
-
-    nsEventStatus status = nsEventStatus_eIgnore;
-    mLastFocusedWindow->DispatchEvent(&compositionChangeEvent, status);
-
-    if (!IsComposing()) {
-        PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
-            ("    FAILED, there is no composition during dispatching "
-             "a compositionchange event for committing the composition"));
-        if (lastFocusedWindow->IsDestroyed() ||
-            lastFocusedWindow != mLastFocusedWindow) {
-            PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
-                ("    NOTE, the focused widget was destroyed/changed by "
-                 "compositionchange event"));
-            return false;
-        }
-        return true;
-    }
-
-    // Next, forget current composition before dispatching a composionend event.
+    uint32_t message = aCommitString ? NS_COMPOSITION_COMMIT :
+                                       NS_COMPOSITION_COMMIT_AS_IS;
     mCompositionState = eCompositionState_NotComposing;
     mCompositionStart = UINT32_MAX;
     mCompositionTargetOffset = UINT32_MAX;
     mDispatchedCompositionString.Truncate();
 
-    // Finally, dispatch a compositionend event if it's possible.
-    if (!lastFocusedWindow->IsDestroyed() &&
-        lastFocusedWindow == mLastFocusedWindow) {
-        WidgetCompositionEvent compositionEndEvent(true, NS_COMPOSITION_END,
-                                                   mLastFocusedWindow);
-        InitEvent(compositionEndEvent);
-        compositionEndEvent.mData = aCommitString;
+    WidgetCompositionEvent compositionCommitEvent(true, message,
+                                                  mLastFocusedWindow);
+    InitEvent(compositionCommitEvent);
+    if (message == NS_COMPOSITION_COMMIT) {
+        compositionCommitEvent.mData = *aCommitString;
+    }
 
-        status = nsEventStatus_eIgnore;
-        mLastFocusedWindow->DispatchEvent(&compositionEndEvent, status);
-    }
+    nsEventStatus status = nsEventStatus_eIgnore;
+    mLastFocusedWindow->DispatchEvent(&compositionCommitEvent, status);
 
     if (lastFocusedWindow->IsDestroyed() ||
         lastFocusedWindow != mLastFocusedWindow) {
         PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
             ("    NOTE, the focused widget was destroyed/changed by "
-             "compositionend event"));
+             "compositioncommit event"));
         return false;
     }
 
     return true;
 }
 
 already_AddRefed<TextRangeArray>
 nsGtkIMModule::CreateTextRangeArray(GtkIMContext* aContext,
@@ -1488,17 +1460,17 @@ nsGtkIMModule::DeleteText(GtkIMContext* 
 
     // First, we should cancel current composition because editor cannot
     // handle changing selection and deleting text.
     uint32_t selOffset;
     bool wasComposing = IsComposing();
     bool editorHadCompositionString = EditorHasCompositionString();
     if (wasComposing) {
         selOffset = mCompositionStart;
-        if (!DispatchCompositionEventsForCommit(aContext, mSelectedString)) {
+        if (!DispatchCompositionCommitEvent(aContext, &mSelectedString)) {
             PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
                 ("    FAILED, quitting from DeletText"));
             return NS_ERROR_FAILURE;
         }
     } else {
         // Query cursor position & selection
         WidgetQueryContentEvent querySelectedTextEvent(true,
                                                        NS_QUERY_SELECTED_TEXT,
--- a/widget/gtk/nsGtkIMModule.h
+++ b/widget/gtk/nsGtkIMModule.h
@@ -123,18 +123,17 @@ protected:
 
     // current target offset of IME composition
     uint32_t mCompositionTargetOffset;
 
     // mCompositionState indicates current status of composition.
     enum eCompositionState {
         eCompositionState_NotComposing,
         eCompositionState_CompositionStartDispatched,
-        eCompositionState_CompositionChangeEventDispatched,
-        eCompositionState_CommitCompositionChangeEventDispatched
+        eCompositionState_CompositionChangeEventDispatched
     };
     eCompositionState mCompositionState;
 
     bool IsComposing()
     {
         return (mCompositionState != eCompositionState_NotComposing);
     }
 
@@ -159,18 +158,16 @@ protected:
     {
         switch (mCompositionState) {
             case eCompositionState_NotComposing:
                 return "NotComposing";
             case eCompositionState_CompositionStartDispatched:
                 return "CompositionStartDispatched";
             case eCompositionState_CompositionChangeEventDispatched:
                 return "CompositionChangeEventDispatched";
-            case eCompositionState_CommitCompositionChangeEventDispatched:
-                return "CommitCompositionChangeEventDispatched";
             default:
                 return "InvaildState";
         }
     }
 #endif // PR_LOGGING
 
 
     // mIsIMFocused is set to TRUE when we call gtk_im_context_focus_in(). And
@@ -312,17 +309,17 @@ protected:
 
     /**
      *  WARNING:
      *    Following methods dispatch gecko events.  Then, the focused widget
      *    can be destroyed, and also it can be stolen focus.  If they returns
      *    FALSE, callers cannot continue the composition.
      *      - DispatchCompositionStart
      *      - DispatchCompositionChangeEvent
-     *      - DispatchCompositionEventsForCommit
+     *      - DispatchCompositionCommitEvent
      */
 
     /**
      * Dispatches a composition start event.
      *
      * @param aContext              A GtkIMContext which is being handled.
      * @return                      true if the focused widget is neither
      *                              destroyed nor changed.  Otherwise, false.
@@ -336,22 +333,24 @@ protected:
      * @param aCompositionString    New composition string.
      * @return                      true if the focused widget is neither
      *                              destroyed nor changed.  Otherwise, false.
      */
     bool DispatchCompositionChangeEvent(GtkIMContext* aContext,
                                         const nsAString& aCompositionString);
 
     /**
-     * Dispatches a compositionchange event for committing the composition
-     * string and a compositionend event.
+     * Dispatches a compositioncommit event or compositioncommitasis event.
      *
      * @param aContext              A GtkIMContext which is being handled.
-     * @param aCommitString         The string which the composition is
-     *                              committed with.
+     * @param aCommitString         If this is nullptr, the composition will
+     *                              be committed with last dispatched data.
+     *                              Otherwise, the composition will be
+     *                              committed with this value.
      * @return                      true if the focused widget is neither
      *                              destroyed nor changed.  Otherwise, false.
      */
-    bool DispatchCompositionEventsForCommit(GtkIMContext* aContext,
-                                            const nsAString& aCommitString);
+    bool DispatchCompositionCommitEvent(
+             GtkIMContext* aContext,
+             const nsAString* aCommitString = nullptr);
 };
 
 #endif // __nsGtkIMModule_h__