Revert "Renamed KeyEvent enum values to comply with coding standards."
[platform/core/uifw/dali-adaptor.git] / dali / internal / input / tizen-wayland / input-method-context-impl-ecore-wl.cpp
index 3abaf47..7482be6 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/public-api/events/key-event.h>
 #include <dali/public-api/adaptor-framework/key.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/common/singleton-service.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
-#include <dali/integration-api/adaptor.h>
-#include <dali/internal/system/common/locale-utils.h>
-#include <dali/internal/system/common/singleton-service-impl.h>
 #include <dali/public-api/adaptor-framework/input-method.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/integration-api/adaptor-framework/scene-holder.h>
 #include <dali/internal/input/common/key-impl.h>
+#include <dali/internal/system/common/locale-utils.h>
 #include <dali/internal/window-system/common/window-render-surface.h>
 
-#define TOKEN_STRING(x) #x
-
 Ecore_IMF_Input_Panel_Layout panelLayoutMap[] =
 {
    ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL,
@@ -97,27 +96,37 @@ namespace
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_INPUT_METHOD_CONTEXT");
 #endif
 
+const int kUninitializedWindowId = 0;
+
 // Currently this code is internal to dali/dali/internal/event/text/utf8.h but should be made Public and used from there instead.
 size_t Utf8SequenceLength(const unsigned char leadByte)
 {
   size_t length = 0;
 
-  if ((leadByte & 0x80) == 0 )          //ASCII character (lead bit zero)
+  if( ( leadByte & 0x80 ) == 0 )         //ASCII character (lead bit zero)
   {
     length = 1;
   }
-  else if (( leadByte & 0xe0 ) == 0xc0 ) //110x xxxx
+  else if( leadByte & 0xe0 ) == 0xc0 ) //110x xxxx
   {
     length = 2;
   }
-  else if (( leadByte & 0xf0 ) == 0xe0 ) //1110 xxxx
+  else if( leadByte & 0xf0 ) == 0xe0 ) //1110 xxxx
   {
     length = 3;
   }
-  else if (( leadByte & 0xf8 ) == 0xf0 ) //1111 0xxx
+  else if( leadByte & 0xf8 ) == 0xf0 ) //1111 0xxx
   {
     length = 4;
   }
+  else if( ( leadByte & 0xfc ) == 0xf8 ) //1111 10xx
+  {
+    length = 5;
+  }
+  else if( ( leadByte & 0xfe ) == 0xfc ) //1111 110x
+  {
+    length = 6;
+  }
 
   return length;
 }
@@ -268,33 +277,41 @@ void CommitContent( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
   }
 }
 
+int GetWindowIdFromActor( Dali::Actor actor )
+{
+  int windowId = kUninitializedWindowId;
+
+  if( actor.GetProperty< bool >( Dali::Actor::Property::CONNECTED_TO_SCENE ) )
+  {
+    Any nativeWindowHandle = Dali::Integration::SceneHolder::Get( actor ).GetNativeHandle();
+
+#ifdef ECORE_WAYLAND2
+    windowId = ecore_wl2_window_id_get( AnyCast< Ecore_Wl2_Window* >( nativeWindowHandle ) );
+#else
+    windowId = ecore_wl_window_id_get( AnyCast< Ecore_Wl_Window* >( nativeWindowHandle ) );
+#endif
+  }
+
+  return windowId;
+}
+
 BaseHandle Create()
 {
-  return Dali::InputMethodContext::New();
+  return Dali::InputMethodContext::New( Dali::Actor() );
 }
 
 Dali::TypeRegistration type( typeid(Dali::InputMethodContext), typeid(Dali::BaseHandle), Create );
 
 } // unnamed namespace
 
-InputMethodContextPtr InputMethodContextEcoreWl::New()
+InputMethodContextPtr InputMethodContextEcoreWl::New( Dali::Actor actor )
 {
   InputMethodContextPtr inputMethodContext;
 
-  // Create instance only if the adaptor is available
-  if ( Dali::Adaptor::IsAvailable() )
+  // Create instance only if the adaptor is available and the valid actor exists
+  if ( actor && Dali::Adaptor::IsAvailable() )
   {
-    Any nativeWindow = Dali::Adaptor::Get().GetNativeWindowHandle();
-
-    // The window needs to use the InputMethodContext.
-    if( !nativeWindow.Empty() )
-    {
-      inputMethodContext = new InputMethodContextEcoreWl();
-    }
-    else
-    {
-      DALI_LOG_ERROR("Failed to get native window handle, can't create InputMethodContext instance.\n");
-    }
+    inputMethodContext = new InputMethodContextEcoreWl( actor );
   }
   return inputMethodContext;
 }
@@ -307,14 +324,17 @@ void InputMethodContextEcoreWl::Finalize()
   DeleteContext();
 }
 
-InputMethodContextEcoreWl::InputMethodContextEcoreWl()
+InputMethodContextEcoreWl::InputMethodContextEcoreWl( Dali::Actor actor )
 : mIMFContext(),
   mIMFCursorPosition( 0 ),
   mSurroundingText(),
   mRestoreAfterFocusLost( false ),
-  mIdleCallbackConnected( false )
+  mIdleCallbackConnected( false ),
+  mWindowId( GetWindowIdFromActor( actor ) )
 {
   ecore_imf_init();
+
+  actor.OnSceneSignal().Connect( this, &InputMethodContextEcoreWl::OnStaged );
 }
 
 InputMethodContextEcoreWl::~InputMethodContextEcoreWl()
@@ -327,12 +347,18 @@ void InputMethodContextEcoreWl::Initialize()
 {
   CreateContext();
   ConnectCallbacks();
+  ApplyBackupOperations();
 }
 
 void InputMethodContextEcoreWl::CreateContext()
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContext::CreateContext\n" );
 
+  if( mWindowId == kUninitializedWindowId )
+  {
+    return;
+  }
+
   const char *contextId = ecore_imf_context_default_id_get();
   if( contextId )
   {
@@ -340,30 +366,16 @@ void InputMethodContextEcoreWl::CreateContext()
 
     if( mIMFContext )
     {
-      // If we fail to get window id, we can't use the InputMethodContext correctly.
-      // Thus you have to call "ecore_imf_context_client_window_set" somewhere.
-
-      Any nativeWindowHandle = Dali::Adaptor::Get().GetNativeWindowHandle();
-
-#ifdef ECORE_WAYLAND2
-      int windowId = ecore_wl2_window_id_get( AnyCast< Ecore_Wl2_Window* >( nativeWindowHandle ) );
-#else
-      int windowId = ecore_wl_window_id_get( AnyCast< Ecore_Wl_Window* >( nativeWindowHandle ) );
-#endif
-
-      if( windowId != 0 )
-      {
-        ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast< void* >( windowId ) );
-      }
+      ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast< void* >( mWindowId ) );
     }
     else
     {
-      DALI_LOG_WARNING("InputMethodContext Unable to get IMFContext\n");
+      DALI_LOG_WARNING( "InputMethodContext Unable to get IMFContext\n" );
     }
   }
   else
   {
-    DALI_LOG_WARNING("InputMethodContext Unable to get IMFContext\n");
+    DALI_LOG_WARNING( "InputMethodContext Unable to get IMFContext\n" );
   }
 }
 
@@ -496,6 +508,8 @@ void InputMethodContextEcoreWl::PreEditChanged( void*, ImfContext* imfContext, v
 
   Ecore_IMF_Preedit_Attr* attr;
 
+  mPreeditAttrs.Clear();
+
   // Retrieves attributes as well as the string the cursor position offset from start of pre-edit string.
   // the attributes (attrs) is used in languages that use the soft arrows keys to insert characters into a current pre-edit string.
   ecore_imf_context_preedit_string_with_attributes_get( context, &preEditString, &attrs, &cursorPosition );
@@ -505,38 +519,88 @@ void InputMethodContextEcoreWl::PreEditChanged( void*, ImfContext* imfContext, v
     // iterate through the list of attributes getting the type, start and end position.
     for ( l = attrs, (attr =  static_cast<Ecore_IMF_Preedit_Attr*>( eina_list_data_get(l) ) ); l; l = eina_list_next(l), ( attr = static_cast<Ecore_IMF_Preedit_Attr*>( eina_list_data_get(l) ) ))
     {
-#ifdef DALI_PROFILE_UBUNTU
-      if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3 ) // (Ecore_IMF)
-#else // DALI_PROFILE_UBUNTU
-      if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB4 ) // (Ecore_IMF)
-#endif // DALI_PROFILE_UBUNTU
-      {
-        // check first byte so know how many bytes a character is represented by as keyboard returns cursor position in bytes. Which is different for some languages.
+      Dali::InputMethodContext::PreeditAttributeData data;
+      data.startIndex = 0;
+      data.endIndex = 0;
 
-        size_t visualCharacterIndex = 0;
-        size_t byteIndex = 0;
+      size_t visualCharacterIndex = 0;
+      size_t byteIndex = 0;
+
+      // iterate through null terminated string checking each character's position against the given byte position ( attr->end_index ).
+      char leadByte = preEditString[byteIndex];
+
+      while( leadByte != '\0' )
+      {
+        leadByte = preEditString[byteIndex]; // Update the character to get the number of its byte
 
-        // iterate through null terminated string checking each character's position against the given byte position ( attr->end_index ).
-        const char leadByte = preEditString[byteIndex];
-        while( leadByte != '\0' )
+        // attr->end_index is provided as a byte position not character and we need to know the character position.
+        const size_t currentSequenceLength = Utf8SequenceLength( leadByte ); // returns number of bytes used to represent character.
+        if( byteIndex <= attr->start_index )
         {
-          // attr->end_index is provided as a byte position not character and we need to know the character position.
-          const size_t currentSequenceLength = Utf8SequenceLength( leadByte ); // returns number of bytes used to represent character.
-          if ( byteIndex == attr->end_index )
-          {
-            cursorPosition = visualCharacterIndex;
-            break;
-            // end loop as found cursor position that matches byte position
-          }
-          else
-          {
-            byteIndex += currentSequenceLength; // jump to next character
-            visualCharacterIndex++;  // increment character count so we know our position for when we get a match
-          }
+           data.startIndex = visualCharacterIndex;
+        }
+        if( byteIndex >= attr->end_index )
+        {
+          data.endIndex = visualCharacterIndex;
+          break;
+          // end loop as found cursor position that matches byte position
+        }
+        else
+        {
+          byteIndex += currentSequenceLength; // jump to next character
+          visualCharacterIndex++;  // increment character count so we know our position for when we get a match
+        }
+      }
 
-          DALI_ASSERT_DEBUG( visualCharacterIndex < strlen( preEditString ));
+      switch( attr->preedit_type )
+      {
+        case ECORE_IMF_PREEDIT_TYPE_NONE:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::NONE;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB1:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::UNDERLINE;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB2:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::REVERSE;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB3:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::HIGHLIGHT;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB4:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_1;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB5:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB6:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB7:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4;
+          break;
+        }
+        default:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::NONE;
+          break;
         }
       }
+      mPreeditAttrs.PushBack( data );
     }
   }
 
@@ -599,33 +663,36 @@ bool InputMethodContextEcoreWl::RetrieveSurrounding( void* data, ImfContext* imf
 
   if( callbackData.update )
   {
+    if( cursorPosition )
+    {
+      mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
+      *cursorPosition = mIMFCursorPosition;
+    }
+
     if( text )
     {
       const char* plainText = callbackData.currentText.c_str();
+
       if( plainText )
       {
+        // The memory allocated by strdup() can be freed by ecore_imf_context_surrounding_get() internally.
+        *text = strdup( plainText );
+
         // If the current input panel is password mode, dali should replace the plain text with '*' (Asterisk) character.
-        if( ecore_imf_context_input_hint_get( mIMFContext ) & ECORE_IMF_INPUT_HINT_SENSITIVE_DATA )
+        if( ( ecore_imf_context_input_hint_get( mIMFContext ) & ECORE_IMF_INPUT_HINT_SENSITIVE_DATA ) && *text )
         {
-          char* iter = NULL;
-          for( iter = const_cast<char*>( plainText ); iter && *iter; ++iter )
+          for( char* iter = *text; *iter; ++iter )
           {
             *iter = '*';
           }
         }
-      }
-      // The memory allocated by strdup() can be freed by ecore_imf_context_surrounding_get() internally.
-      *text = strdup( plainText );
-    }
 
-    if( cursorPosition )
-    {
-      mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
-      *cursorPosition = mIMFCursorPosition;
+        return EINA_TRUE;
+      }
     }
   }
 
-  return EINA_TRUE;
+  return EINA_FALSE;
 }
 
 /**
@@ -722,11 +789,16 @@ const std::string& InputMethodContextEcoreWl::GetSurroundingText() const
 
 void InputMethodContextEcoreWl::NotifyTextInputMultiLine( bool multiLine )
 {
-  Ecore_IMF_Input_Hints currentHint = ecore_imf_context_input_hint_get(mIMFContext);
-  ecore_imf_context_input_hint_set( mIMFContext,
-                                    static_cast< Ecore_IMF_Input_Hints >( multiLine ?
-                                      (currentHint | ECORE_IMF_INPUT_HINT_MULTILINE) :
-                                      (currentHint & ~ECORE_IMF_INPUT_HINT_MULTILINE)));
+  if( mIMFContext )
+  {
+    Ecore_IMF_Input_Hints currentHint = ecore_imf_context_input_hint_get(mIMFContext);
+    ecore_imf_context_input_hint_set( mIMFContext,
+                                      static_cast< Ecore_IMF_Input_Hints >( multiLine ?
+                                        (currentHint | ECORE_IMF_INPUT_HINT_MULTILINE) :
+                                        (currentHint & ~ECORE_IMF_INPUT_HINT_MULTILINE)));
+  }
+
+  mBackupOperations[Operation::NOTIFY_TEXT_INPUT_MULTILINE] = std::bind( &InputMethodContextEcoreWl::NotifyTextInputMultiLine, this, multiLine );
 }
 
 Dali::InputMethodContext::TextDirection InputMethodContextEcoreWl::GetTextDirection()
@@ -816,6 +888,8 @@ void InputMethodContextEcoreWl::SetInputPanelData( const std::string& data )
     int length = data.length();
     ecore_imf_context_input_panel_imdata_set( mIMFContext, data.c_str(), length );
   }
+
+  mBackupOperations[Operation::SET_INPUT_PANEL_DATA] = std::bind( &InputMethodContextEcoreWl::SetInputPanelData, this, data );
 }
 
 void InputMethodContextEcoreWl::GetInputPanelData( std::string& data )
@@ -878,6 +952,8 @@ void InputMethodContextEcoreWl::SetReturnKeyState( bool visible )
   {
     ecore_imf_context_input_panel_return_key_disabled_set( mIMFContext, !visible );
   }
+
+  mBackupOperations[Operation::SET_RETURN_KEY_STATE] = std::bind( &InputMethodContextEcoreWl::SetReturnKeyState, this, visible );
 }
 
 void InputMethodContextEcoreWl::AutoEnableInputPanel( bool enabled )
@@ -888,6 +964,8 @@ void InputMethodContextEcoreWl::AutoEnableInputPanel( bool enabled )
   {
     ecore_imf_context_input_panel_enabled_set( mIMFContext, enabled );
   }
+
+  mBackupOperations[Operation::AUTO_ENABLE_INPUT_PANEL] = std::bind( &InputMethodContextEcoreWl::AutoEnableInputPanel, this, enabled );
 }
 
 void InputMethodContextEcoreWl::ShowInputPanel()
@@ -968,6 +1046,8 @@ void InputMethodContextEcoreWl::SetContentMIMETypes( const std::string& mimeType
   {
     ecore_imf_context_mime_type_accept_set( mIMFContext, mimeTypes.c_str() );
   }
+
+  mBackupOperations[Operation::SET_CONTENT_MIME_TYPES] = std::bind( &InputMethodContextEcoreWl::SetContentMIMETypes, this, mimeTypes );
 }
 
 bool InputMethodContextEcoreWl::FilterEventKey( const Dali::KeyEvent& keyEvent )
@@ -975,14 +1055,14 @@ bool InputMethodContextEcoreWl::FilterEventKey( const Dali::KeyEvent& keyEvent )
   bool eventHandled( false );
 
   // If a device key then skip ecore_imf_context_filter_event.
-  if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ))
+  if ( ! KeyLookup::IsDeviceButton( keyEvent.GetKeyName().c_str() ))
   {
     //check whether it's key down or key up event
-    if ( keyEvent.state == KeyEvent::Down )
+    if ( keyEvent.GetState() == Dali::KeyEvent::Down )
     {
       eventHandled = ProcessEventKeyDown( keyEvent );
     }
-    else if ( keyEvent.state == KeyEvent::Up )
+    else if ( keyEvent.GetState() == Dali::KeyEvent::Up )
     {
       eventHandled = ProcessEventKeyUp( keyEvent );
     }
@@ -999,6 +1079,8 @@ void InputMethodContextEcoreWl::AllowTextPrediction( bool prediction )
   {
     ecore_imf_context_prediction_allow_set( mIMFContext, prediction );
   }
+
+  mBackupOperations[Operation::ALLOW_TEXT_PREDICTION] = std::bind( &InputMethodContextEcoreWl::AllowTextPrediction, this, prediction );
 }
 
 bool InputMethodContextEcoreWl::IsTextPredictionAllowed() const
@@ -1031,6 +1113,8 @@ void InputMethodContextEcoreWl::SetInputPanelLanguage( Dali::InputMethodContext:
       }
     }
   }
+
+  mBackupOperations[Operation::SET_INPUT_PANEL_LANGUAGE] = std::bind( &InputMethodContextEcoreWl::SetInputPanelLanguage, this, language );
 }
 
 Dali::InputMethodContext::InputPanelLanguage InputMethodContextEcoreWl::GetInputPanelLanguage() const
@@ -1058,35 +1142,56 @@ Dali::InputMethodContext::InputPanelLanguage InputMethodContextEcoreWl::GetInput
   return Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC;
 }
 
-bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent )
+void InputMethodContextEcoreWl::SetInputPanelPosition( unsigned int x, unsigned int y )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetInputPanelPosition\n" );
+
+  if( mIMFContext )
+  {
+    ecore_imf_context_input_panel_position_set( mIMFContext, x, y );
+  }
+
+  mBackupOperations[Operation::SET_INPUT_PANEL_POSITION] = std::bind( &InputMethodContextEcoreWl::SetInputPanelPosition, this, x, y );
+}
+
+void InputMethodContextEcoreWl::GetPreeditStyle( Dali::InputMethodContext::PreEditAttributeDataContainer& attrs ) const
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetPreeditStyle\n" );
+  attrs = mPreeditAttrs;
+}
+
+bool InputMethodContextEcoreWl::ProcessEventKeyDown( const Dali::KeyEvent& keyEvent )
 {
   bool eventHandled( false );
   if ( mIMFContext )
   {
-    Integration::KeyEvent integKeyEvent( keyEvent );
+    Integration::KeyEvent integKeyEvent( keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast< Integration::KeyEvent::State >( keyEvent.GetState() ), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass() );
     std::string key = integKeyEvent.logicalKey;
 
-    std::string compose = keyEvent.GetCompose();
-    std::string deviceName = keyEvent.GetDeviceName();
+    std::string compose = integKeyEvent.compose;
+    std::string deviceName = integKeyEvent.deviceName;
 
     // We're consuming key down event so we have to pass to InputMethodContext so that it can parse it as well.
     Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
-    ecoreKeyDownEvent.keyname = keyEvent.keyPressedName.c_str();
+    ecoreKeyDownEvent.keyname = integKeyEvent.keyName.c_str();
     ecoreKeyDownEvent.key = key.c_str();
-    ecoreKeyDownEvent.string = keyEvent.keyPressed.c_str();
+    ecoreKeyDownEvent.string = integKeyEvent.keyString.c_str();
     ecoreKeyDownEvent.compose = compose.c_str();
-    ecoreKeyDownEvent.timestamp = keyEvent.time;
-    ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( keyEvent.keyModifier );
-    ecoreKeyDownEvent.locks = EcoreInputModifierToEcoreIMFLock( keyEvent.keyModifier );
+    ecoreKeyDownEvent.timestamp = integKeyEvent.time;
+    ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( integKeyEvent.keyModifier );
+    ecoreKeyDownEvent.locks = EcoreInputModifierToEcoreIMFLock( integKeyEvent.keyModifier );
     ecoreKeyDownEvent.dev_name = deviceName.c_str();
-    ecoreKeyDownEvent.dev_class = static_cast<Ecore_IMF_Device_Class> ( keyEvent.GetDeviceClass() );//ECORE_IMF_DEVICE_CLASS_KEYBOARD;
-    ecoreKeyDownEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass> ( keyEvent.GetDeviceSubclass() );//ECORE_IMF_DEVICE_SUBCLASS_NONE;
+    ecoreKeyDownEvent.dev_class = static_cast<Ecore_IMF_Device_Class> ( integKeyEvent.deviceClass );//ECORE_IMF_DEVICE_CLASS_KEYBOARD;
+    ecoreKeyDownEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass> ( integKeyEvent.deviceSubclass );//ECORE_IMF_DEVICE_SUBCLASS_NONE;
+#if defined(ECORE_VERSION_MAJOR) && (ECORE_VERSION_MAJOR >= 1) && defined(ECORE_VERSION_MINOR) && (ECORE_VERSION_MINOR >= 22)
+    ecoreKeyDownEvent.keycode = integKeyEvent.keyCode; // Ecore_IMF_Event structure has added 'keycode' variable since ecore_imf 1.22 version.
+#endif // Since ecore_imf 1.22 version
 
     // If the device is IME and the focused key is the direction keys, then we should send a key event to move a key cursor.
-    if ((keyEvent.GetDeviceName() == "ime") && ((!strncmp(keyEvent.keyPressedName.c_str(), "Left", 4)) ||
-                                   (!strncmp(keyEvent.keyPressedName.c_str(), "Right", 5)) ||
-                                   (!strncmp(keyEvent.keyPressedName.c_str(), "Up", 2)) ||
-                                   (!strncmp(keyEvent.keyPressedName.c_str(), "Down", 4))))
+    if ((integKeyEvent.deviceName == "ime") && ((!strncmp(integKeyEvent.keyName.c_str(), "Left", 4)) ||
+                                   (!strncmp(integKeyEvent.keyName.c_str(), "Right", 5)) ||
+                                   (!strncmp(integKeyEvent.keyName.c_str(), "Up", 2)) ||
+                                   (!strncmp(integKeyEvent.keyName.c_str(), "Down", 4))))
     {
       eventHandled = 0;
     }
@@ -1100,9 +1205,9 @@ bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent )
     // If the event has not been handled by InputMethodContext then check if we should reset our input method context
     if (!eventHandled)
     {
-      if (!strcmp(keyEvent.keyPressedName.c_str(), "Escape") ||
-          !strcmp(keyEvent.keyPressedName.c_str(), "Return") ||
-          !strcmp(keyEvent.keyPressedName.c_str(), "KP_Enter"))
+      if (!strcmp(integKeyEvent.keyName.c_str(), "Escape") ||
+          !strcmp(integKeyEvent.keyName.c_str(), "Return") ||
+          !strcmp(integKeyEvent.keyName.c_str(), "KP_Enter"))
       {
         ecore_imf_context_reset(mIMFContext);
       }
@@ -1111,29 +1216,32 @@ bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent )
   return eventHandled;
 }
 
-bool InputMethodContextEcoreWl::ProcessEventKeyUp( const KeyEvent& keyEvent )
+bool InputMethodContextEcoreWl::ProcessEventKeyUp( const Dali::KeyEvent& keyEvent )
 {
   bool eventHandled( false );
   if( mIMFContext )
   {
-    Integration::KeyEvent integKeyEvent( keyEvent );
+    Integration::KeyEvent integKeyEvent( keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast< Integration::KeyEvent::State >( keyEvent.GetState() ), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass() );
     std::string key = integKeyEvent.logicalKey;
 
-    std::string compose = keyEvent.GetCompose();
-    std::string deviceName = keyEvent.GetDeviceName();
+    std::string compose = integKeyEvent.compose;
+    std::string deviceName = integKeyEvent.deviceName;
 
     // We're consuming key up event so we have to pass to InputMethodContext so that it can parse it as well.
     Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
-    ecoreKeyUpEvent.keyname = keyEvent.keyPressedName.c_str();
+    ecoreKeyUpEvent.keyname = integKeyEvent.keyName.c_str();
     ecoreKeyUpEvent.key = key.c_str();
-    ecoreKeyUpEvent.string = keyEvent.keyPressed.c_str();
+    ecoreKeyUpEvent.string = integKeyEvent.keyString.c_str();
     ecoreKeyUpEvent.compose = compose.c_str();
-    ecoreKeyUpEvent.timestamp = keyEvent.time;
-    ecoreKeyUpEvent.modifiers =  EcoreInputModifierToEcoreIMFModifier( keyEvent.keyModifier );
-    ecoreKeyUpEvent.locks = EcoreInputModifierToEcoreIMFLock( keyEvent.keyModifier );
+    ecoreKeyUpEvent.timestamp = integKeyEvent.time;
+    ecoreKeyUpEvent.modifiers =  EcoreInputModifierToEcoreIMFModifier( integKeyEvent.keyModifier );
+    ecoreKeyUpEvent.locks = EcoreInputModifierToEcoreIMFLock( integKeyEvent.keyModifier );
     ecoreKeyUpEvent.dev_name = deviceName.c_str();
-    ecoreKeyUpEvent.dev_class = static_cast<Ecore_IMF_Device_Class> ( keyEvent.GetDeviceClass() );//ECORE_IMF_DEVICE_CLASS_KEYBOARD;
-    ecoreKeyUpEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass> ( keyEvent.GetDeviceSubclass() );//ECORE_IMF_DEVICE_SUBCLASS_NONE;
+    ecoreKeyUpEvent.dev_class = static_cast<Ecore_IMF_Device_Class> ( integKeyEvent.deviceClass );//ECORE_IMF_DEVICE_CLASS_KEYBOARD;
+    ecoreKeyUpEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass> ( integKeyEvent.deviceSubclass );//ECORE_IMF_DEVICE_SUBCLASS_NONE;
+#if defined(ECORE_VERSION_MAJOR) && (ECORE_VERSION_MAJOR >= 1) && defined(ECORE_VERSION_MINOR) && (ECORE_VERSION_MINOR >= 22)
+    ecoreKeyUpEvent.keycode = integKeyEvent.keyCode; // Ecore_IMF_Event structure has added 'keycode' variable since ecore_imf 1.22 version.
+#endif // Since ecore_imf 1.22 version
 
     eventHandled = ecore_imf_context_filter_event(mIMFContext,
                                                   ECORE_IMF_EVENT_KEY_UP,
@@ -1196,6 +1304,20 @@ Ecore_IMF_Keyboard_Locks InputMethodContextEcoreWl::EcoreInputModifierToEcoreIMF
     return static_cast<Ecore_IMF_Keyboard_Locks>( lock );
 }
 
+void InputMethodContextEcoreWl::OnStaged( Dali::Actor actor )
+{
+  int windowId = GetWindowIdFromActor( actor );
+
+  if( mWindowId != windowId )
+  {
+    mWindowId = windowId;
+
+    // Reset
+    Finalize();
+    Initialize();
+  }
+}
+
 } // Adaptor
 
 } // Internal