Fix Chinese text issue
authorSangYong Park <sy302.park@samsung.com>
Thu, 10 Oct 2013 08:32:08 +0000 (17:32 +0900)
committerSangYong Park <sy302.park@samsung.com>
Fri, 11 Oct 2013 00:16:59 +0000 (09:16 +0900)
[Title] Fix Chinese text issue
[Issue#] N_SE-51954
[Problem] English text was entered when keyboard and touch input quickly mixed.
[Cause] Keyboard event was handled in ui process before touch event result was not arrived in web process.
[Solution] Process keyboard event again in ui process.

Change-Id: I121cbe55738ecdccffdfaab0a0cef3c685f2a476

12 files changed:
Source/WebKit2/Shared/NativeWebKeyboardEvent.h
Source/WebKit2/Shared/tizen/NativeWebKeyboardEventTizen.cpp
Source/WebKit2/UIProcess/API/efl/ewk_view.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/UIProcess/efl/InputMethodContextEfl.cpp
Source/WebKit2/UIProcess/efl/InputMethodContextEfl.h
Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp
Source/WebKit2/WebProcess/WebCoreSupport/efl/WebEditorClientEfl.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in

index 18f4943..a800a8a 100755 (executable)
@@ -41,16 +41,26 @@ typedef union _GdkEvent GdkEvent;
 #elif PLATFORM(EFL)
 #include <Evas.h>
 #include <Ecore_IMF.h>
-#if ENABLE(TIZEN_ISF_PORT)
-typedef struct {
-    Ecore_IMF_Event_Type type;
-    Ecore_IMF_Event event;
-} EvasImfEvent;
-#endif
 #endif
 
 namespace WebKit {
 
+#if ENABLE(TIZEN_ISF_PORT)
+class EcoreIMFEvent : public RefCounted<EcoreIMFEvent> {
+public:
+    EcoreIMFEvent(const Evas_Event_Key_Down*);
+    EcoreIMFEvent(const Evas_Event_Key_Up*);
+    ~EcoreIMFEvent();
+
+    Ecore_IMF_Event_Type type() const { return m_type; }
+    const Ecore_IMF_Event* event() const { return &m_event; }
+
+private:
+    Ecore_IMF_Event_Type m_type;
+    Ecore_IMF_Event m_event;
+};
+#endif
+
 class NativeWebKeyboardEvent : public WebKeyboardEvent {
 public:
 #if USE(APPKIT)
@@ -63,11 +73,11 @@ public:
     NativeWebKeyboardEvent(const NativeWebKeyboardEvent&);
     NativeWebKeyboardEvent(GdkEvent*);
 #elif PLATFORM(EFL)
+    NativeWebKeyboardEvent(const Evas_Event_Key_Down*, bool);
+    NativeWebKeyboardEvent(const Evas_Event_Key_Up*);
 #if ENABLE(TIZEN_ISF_PORT)
     NativeWebKeyboardEvent();
 #endif
-    NativeWebKeyboardEvent(const Evas_Event_Key_Down*, bool);
-    NativeWebKeyboardEvent(const Evas_Event_Key_Up*);
 #endif
 
 #if USE(APPKIT)
@@ -80,8 +90,11 @@ public:
     GdkEvent* nativeEvent() const { return m_nativeEvent.get(); }
 #elif PLATFORM(EFL)
 #if ENABLE(TIZEN_ISF_PORT)
-    const EvasImfEvent* nativeEvent() const { return &m_nativeEvent; }
-    bool isFiltered() const { return m_filtered; }
+    const EcoreIMFEvent* nativeEvent() const { return m_nativeEvent.get(); }
+    bool isFiltered() const { return m_isFiltered; }
+
+    void setInputMethodContextID(uintptr_t id) { m_inputMethodContextID = id; }
+    uintptr_t inputMethodContextID() const { return m_inputMethodContextID; }
 
     void encode(CoreIPC::ArgumentEncoder*) const;
     static bool decode(CoreIPC::ArgumentDecoder*, NativeWebKeyboardEvent&);
@@ -102,8 +115,9 @@ private:
     GOwnPtr<GdkEvent> m_nativeEvent;
 #elif PLATFORM(EFL)
 #if ENABLE(TIZEN_ISF_PORT)
-    EvasImfEvent m_nativeEvent;
-    bool m_filtered;
+    RefPtr<EcoreIMFEvent> m_nativeEvent;
+    bool m_isFiltered;
+    uintptr_t m_inputMethodContextID;
 #else
     const void* m_nativeEvent;
     bool m_isFiltered;
index 3b6c014..94bc52f 100644 (file)
 
 namespace WebKit {
 
-NativeWebKeyboardEvent::NativeWebKeyboardEvent(const Evas_Event_Key_Down* event, bool filtered)
+EcoreIMFEvent::EcoreIMFEvent(const Evas_Event_Key_Down* event)
+    : m_type(ECORE_IMF_EVENT_KEY_DOWN)
+{
+    Ecore_IMF_Event_Key_Down* keyDownEvent = &m_event.key_down;
+
+    ecore_imf_evas_event_key_down_wrap(const_cast<Evas_Event_Key_Down*>(event), keyDownEvent);
+
+    if (keyDownEvent->keyname)
+        keyDownEvent->keyname = strdup(keyDownEvent->keyname);
+    if (keyDownEvent->key)
+        keyDownEvent->key = strdup(keyDownEvent->key);
+    if (keyDownEvent->string)
+        keyDownEvent->string = strdup(keyDownEvent->string);
+    if (keyDownEvent->compose)
+        keyDownEvent->compose = strdup(keyDownEvent->compose);
+}
+
+EcoreIMFEvent::EcoreIMFEvent(const Evas_Event_Key_Up* event)
+    : m_type(ECORE_IMF_EVENT_KEY_UP)
+{
+    Ecore_IMF_Event_Key_Up* keyUpEvent = &m_event.key_up;
+
+    ecore_imf_evas_event_key_up_wrap(const_cast<Evas_Event_Key_Up*>(event), keyUpEvent);
+
+    if (keyUpEvent->keyname)
+        keyUpEvent->keyname = strdup(keyUpEvent->keyname);
+    if (keyUpEvent->key)
+        keyUpEvent->key = strdup(keyUpEvent->key);
+    if (keyUpEvent->string)
+        keyUpEvent->string = strdup(keyUpEvent->string);
+    if (keyUpEvent->compose)
+        keyUpEvent->compose = strdup(keyUpEvent->compose);
+}
+
+EcoreIMFEvent::~EcoreIMFEvent()
+{
+    if (m_type == ECORE_IMF_EVENT_KEY_DOWN) {
+        Ecore_IMF_Event_Key_Down* keyDownEvent = &m_event.key_down;
+        if (keyDownEvent->keyname)
+            free(const_cast<char*>(keyDownEvent->keyname));
+        if (keyDownEvent->key)
+            free(const_cast<char*>(keyDownEvent->key));
+        if (keyDownEvent->string)
+            free(const_cast<char*>(keyDownEvent->string));
+        if (keyDownEvent->compose)
+            free(const_cast<char*>(keyDownEvent->compose));
+    } else if (m_type == ECORE_IMF_EVENT_KEY_UP) {
+        Ecore_IMF_Event_Key_Up* keyUpEvent = &m_event.key_up;
+        if (keyUpEvent->keyname)
+            free(const_cast<char*>(keyUpEvent->keyname));
+        if (keyUpEvent->key)
+            free(const_cast<char*>(keyUpEvent->key));
+        if (keyUpEvent->string)
+            free(const_cast<char*>(keyUpEvent->string));
+        if (keyUpEvent->compose)
+            free(const_cast<char*>(keyUpEvent->compose));
+    }
+}
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(const Evas_Event_Key_Down* event, bool isFiltered)
     : WebKeyboardEvent(WebEventFactory::createWebKeyboardEvent(event))
-    , m_filtered(filtered)
+    , m_nativeEvent(adoptRef(new EcoreIMFEvent(event)))
+    , m_isFiltered(isFiltered)
+    , m_inputMethodContextID(0)
 {
-    m_nativeEvent.type = ECORE_IMF_EVENT_KEY_DOWN;
-    ecore_imf_evas_event_key_down_wrap(const_cast<Evas_Event_Key_Down*>(event), &m_nativeEvent.event.key_down);
 }
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent(const Evas_Event_Key_Up* event)
     : WebKeyboardEvent(WebEventFactory::createWebKeyboardEvent(event))
-    , m_filtered(false)
+    , m_nativeEvent(adoptRef(new EcoreIMFEvent(event)))
+    , m_isFiltered(false)
+    , m_inputMethodContextID(0)
 {
-    m_nativeEvent.type = ECORE_IMF_EVENT_KEY_UP;
-    ecore_imf_evas_event_key_up_wrap(const_cast<Evas_Event_Key_Up*>(event), &m_nativeEvent.event.key_up);
 }
 
 NativeWebKeyboardEvent::NativeWebKeyboardEvent()
-    : m_filtered(false)
+    : m_isFiltered(false)
+    , m_inputMethodContextID(0)
 {
 }
 
 void NativeWebKeyboardEvent::encode(CoreIPC::ArgumentEncoder* encoder) const
 {
     WebKeyboardEvent::encode(encoder);
-    encoder->encode(m_filtered);
+    encoder->encode(m_isFiltered);
+    encoder->encode(m_inputMethodContextID);
 }
 
 bool NativeWebKeyboardEvent::decode(CoreIPC::ArgumentDecoder* decoder, NativeWebKeyboardEvent& result)
@@ -63,7 +124,10 @@ bool NativeWebKeyboardEvent::decode(CoreIPC::ArgumentDecoder* decoder, NativeWeb
     if (!WebKeyboardEvent::decode(decoder, result))
         return false;
 
-    if (!decoder->decode(result.m_filtered))
+    if (!decoder->decode(result.m_isFiltered))
+        return false;
+
+    if (!decoder->decode(result.m_inputMethodContextID))
         return false;
 
     return true;
index c9e3cca..30dd595 100755 (executable)
@@ -399,7 +399,14 @@ static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* smartData, const
     if (inputMethodContext)
         inputMethodContext->handleKeyDownEvent(downEvent, &isFiltered);
 
+#if ENABLE(TIZEN_ISF_PORT)
+    NativeWebKeyboardEvent nativeEvent(downEvent, isFiltered);
+    nativeEvent.setInputMethodContextID(impl->pageProxy->editorState().inputMethodContextID);
+    impl->pageProxy->handleKeyboardEvent(nativeEvent);
+#else
     impl->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(downEvent, isFiltered));
+#endif
+
     return true;
 }
 
index b30028c..2d508d6 100755 (executable)
@@ -962,6 +962,7 @@ public:
 
     void didCancelComposition();
     void removeInputMethodContext(uintptr_t);
+    void recalcFilterEvent(const EditorState&, bool, bool&);
 #endif
 
     void setBackgroundColor(double red, double green, double blue, double alpha);
index cd21189..4a5e78d 100755 (executable)
@@ -345,9 +345,6 @@ messages -> WebPageProxy {
 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
     TextChangeInTextField(WTF::String name, WTF::String value)
 #endif
-#if ENABLE(TIZEN_ISF_PORT)
-    DidCancelComposition()
-#endif
 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
     SaveSerializedHTMLDataForMainPage(WTF::String name, WTF::String value);
     SaveSubresourcesData(Vector<WebKit::WebSubresourceTizen> subresources);
@@ -474,7 +471,9 @@ messages -> WebPageProxy {
 #endif
 
 #if ENABLE(TIZEN_ISF_PORT)
+    DidCancelComposition()
     RemoveInputMethodContext(uintptr_t id)
+    RecalcFilterEvent(WebKit::EditorState editorState, bool isStart) -> (bool isFiltered)
 #endif
 
 #if ENABLE(TIZEN_WEBKIT2_NOTIFY_SUSPEND_BY_REMOTE_WEB_INSPECTOR)
index f9b4fe3..afec658 100755 (executable)
@@ -901,6 +901,18 @@ void InputMethodContextEfl::updateApproximateText(const String& text, unsigned r
             m_approximateCursorPosition = removePosition;
     }
 }
+
+bool InputMethodContextEfl::recalcFilterEvent(const Ecore_IMF_Event* event)
+{
+    if (!m_context)
+        return false;
+
+    m_doNotHandleFakeKeyEvent = true;
+    bool isFiltered = ecore_imf_context_filter_event(m_context.get(), ECORE_IMF_EVENT_KEY_DOWN, const_cast<Ecore_IMF_Event*>(event));
+    m_doNotHandleFakeKeyEvent = false;
+
+    return isFiltered;
+}
 #endif // #if ENABLE(TIZEN_ISF_PORT)
 
 }
index fecea96..3cd4cfc 100755 (executable)
@@ -70,6 +70,7 @@ public:
     bool isIMEPostion(int, int);
     void removeIMFContext(uintptr_t);
     int state() { return m_state; }
+    bool recalcFilterEvent(const Ecore_IMF_Event*);
 #endif
 
 private:
index aa298aa..306f328 100755 (executable)
@@ -315,6 +315,29 @@ void WebPageProxy::removeInputMethodContext(uintptr_t id)
 
     inputMethodContext->removeIMFContext(id);
 }
+
+void WebPageProxy::recalcFilterEvent(const EditorState& editorState, bool isStart, bool& isFiltered)
+{
+    if (isStart)
+        process()->send(Messages::WebPage::EndRecalcFilterEvent(), m_pageID);
+
+    editorStateChanged(editorState);
+    isFiltered = false;
+
+    InputMethodContextEfl* inputMethodContext = static_cast<PageClientImpl*>(m_pageClient)->viewImpl()->inputMethodContext();
+    if (!inputMethodContext || m_keyEventQueue.isEmpty())
+        return;
+
+#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
+    NativeWebKeyboardEvent event = m_keyEventQueue.first().forwardedEvent;
+#else
+    NativeWebKeyboardEvent event = m_keyEventQueue.first();
+#endif
+    if (!event.nativeEvent() || event.nativeEvent()->type() != ECORE_IMF_EVENT_KEY_DOWN)
+        return;
+
+    isFiltered = inputMethodContext->recalcFilterEvent(event.nativeEvent()->event());
+}
 #endif // #if ENABLE(TIZEN_ISF_PORT)
 
 void WebPageProxy::requestUpdateFormNavigation()
index 338ffe5..f94e5fe 100755 (executable)
@@ -59,6 +59,16 @@ static bool handleKeyPressCommands(WebPage* page, KeyboardEvent* event)
         return isFiltered;
 
     Vector<OwnPtr<KeyPressCommand> > commands;
+    bool recalcFilterEvent = page->recalcFilterEvent();
+    const EditorState& editorState = page->currentEditorState();
+
+    if (recalcFilterEvent || currentEvent->inputMethodContextID() != editorState.inputMethodContextID) {
+        if (!recalcFilterEvent)
+            page->startRecalcFilterEvent();
+        page->sendSync(Messages::WebPageProxy::RecalcFilterEvent(editorState, !recalcFilterEvent), Messages::WebPageProxy::RecalcFilterEvent::Reply(isFiltered));
+        return isFiltered;
+    }
+
     page->swapKeyPressCommands(commands);
 
     size_t size = commands.size();
index 848ea1f..4421d23 100755 (executable)
@@ -304,6 +304,7 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
     , m_inspectorClient(0)
 #if ENABLE(TIZEN_ISF_PORT)
     , m_prepareKeyDownEvent(false)
+    , m_recalcFilterEvent(false)
 #endif
 {
     ASSERT(m_pageID);
index 6a1aafc..1f3c89a 100755 (executable)
@@ -275,6 +275,10 @@ public:
     void swapKeyPressCommands(Vector<OwnPtr<KeyPressCommand> >&);
 
     void deleteSurroundingText(int, int);
+
+    bool recalcFilterEvent() const { return m_recalcFilterEvent; }
+    void startRecalcFilterEvent() { m_recalcFilterEvent = true; }
+    void endRecalcFilterEvent() { m_recalcFilterEvent = false; }
 #endif
     void scrollMainFrameBy(const WebCore::IntSize&);
     void scrollMainFrameTo(const WebCore::IntPoint&);
@@ -1230,6 +1234,7 @@ private:
 #if ENABLE(TIZEN_ISF_PORT)
     bool m_prepareKeyDownEvent;
     Vector<OwnPtr<KeyPressCommand> > m_keyPressCommands;
+    bool m_recalcFilterEvent;
 #endif
 };
 
index a6cc940..17e8629 100755 (executable)
@@ -350,6 +350,7 @@ messages -> WebPage {
 #if ENABLE(TIZEN_ISF_PORT)
     PrepareKeyDownEvent()
     DeleteSurroundingText(int offset, int count)
+    EndRecalcFilterEvent()
 #endif
 #endif
 #if PLATFORM(EFL)