Fix InputMethodContext to work well in multi-window env 09/208609/9
authorJiyun Yang <ji.yang@samsung.com>
Wed, 26 Jun 2019 06:55:18 +0000 (15:55 +0900)
committerJiyun Yang <ji.yang@samsung.com>
Wed, 28 Aug 2019 05:33:40 +0000 (14:33 +0900)
Change-Id: I6ddb1442b03d45b483b484df9c50424061b21133
Signed-off-by: Jiyun Yang <ji.yang@samsung.com>
23 files changed:
dali/devel-api/adaptor-framework/input-method-context.cpp
dali/devel-api/adaptor-framework/input-method-context.h
dali/integration-api/adaptor.h
dali/integration-api/scene-holder-impl.cpp
dali/integration-api/scene-holder-impl.h
dali/integration-api/scene-holder.cpp
dali/integration-api/scene-holder.h
dali/internal/adaptor/common/adaptor-impl.cpp
dali/internal/adaptor/common/adaptor-impl.h
dali/internal/adaptor/common/adaptor.cpp
dali/internal/input/common/input-method-context-factory.h
dali/internal/input/common/input-method-context-impl.cpp
dali/internal/input/common/input-method-context-impl.h
dali/internal/input/tizen-wayland/input-method-context-factory-ecore-wl.cpp
dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp
dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.h
dali/internal/input/ubuntu-x11/input-method-context-factory-x.cpp
dali/internal/input/ubuntu-x11/input-method-context-impl-x.cpp
dali/internal/input/ubuntu-x11/input-method-context-impl-x.h
dali/internal/input/windows/input-method-context-factory-win.cpp
dali/internal/input/windows/input-method-context-impl-win.cpp
dali/internal/input/windows/input-method-context-impl-win.h
dali/internal/window-system/common/window-impl.cpp

index e5deaca..492b9ae 100755 (executable)
@@ -32,7 +32,12 @@ InputMethodContext::~InputMethodContext() = default;
 
 InputMethodContext InputMethodContext::New()
 {
-  Internal::Adaptor::InputMethodContextPtr inputMethodContext = Internal::Adaptor::InputMethodContext::New();
+  return InputMethodContext::New( Actor() );
+}
+
+InputMethodContext InputMethodContext::New( Actor actor )
+{
+  Internal::Adaptor::InputMethodContextPtr inputMethodContext = Internal::Adaptor::InputMethodContext::New( actor );
 
   if( inputMethodContext )
   {
index e67f5fd..4310c77 100755 (executable)
@@ -37,6 +37,8 @@ class InputMethodContext;
 }
 }
 
+class Actor;
+
 /**
  * @brief The InputMethodContext class
  *
@@ -201,6 +203,13 @@ public:
   static InputMethodContext New();
 
   /**
+   * @brief Create a new instance of an InputMethodContext.
+   *
+   * @param[in] actor The actor that uses the new InputMethodContext instance.
+   */
+  static InputMethodContext New( Actor actor );
+
+  /**
    * @brief Copy constructor.
    *
    * @param[in] inputMethodContext InputMethodContext to copy. The copied inputMethodContext will point at the same implementation.
index 2bce86e..cb19fa0 100755 (executable)
@@ -308,6 +308,14 @@ public:
   Any GetNativeWindowHandle();
 
   /**
+   * @brief Retrieve native window handle that the given actor is added to.
+   *
+   * @param[in] actor The actor
+   * @return native window handle
+   */
+  Any GetNativeWindowHandle( Actor actor );
+
+  /**
    * @brief Get the native display associated with the graphics backend
    *
    * @return A handle to the native display
index 3a7bc5a..a5eca04 100644 (file)
@@ -337,6 +337,19 @@ void SceneHolder::FeedKeyEvent( Dali::Integration::KeyEvent& keyEvent )
   mAdaptor->ProcessCoreEvents();
 }
 
+Dali::Integration::SceneHolder SceneHolder::Get( Dali::Actor actor )
+{
+  SceneHolder* sceneHolderImpl = nullptr;
+
+  if ( Internal::Adaptor::Adaptor::IsAvailable() )
+  {
+    Dali::Internal::Adaptor::Adaptor& adaptor = Internal::Adaptor::Adaptor::GetImplementation( Internal::Adaptor::Adaptor::Get() );
+    sceneHolderImpl = adaptor.GetWindow( actor );
+  }
+
+  return Dali::Integration::SceneHolder( sceneHolderImpl );
+}
+
 void SceneHolder::Reset()
 {
   mCombiner.Reset();
index 6b4e488..78682ea 100644 (file)
@@ -167,6 +167,11 @@ public:
    */
   void FeedKeyEvent( Dali::Integration::KeyEvent& keyEvent );
 
+  /**
+   * @copydoc Dali::Integration::SceneHolder::Get()
+   */
+  static Dali::Integration::SceneHolder Get( Dali::Actor actor );
+
 public: // The following methods can be overridden if required
 
   /**
index ca5e4f4..8f456d9 100644 (file)
@@ -83,6 +83,11 @@ Vector4 SceneHolder::GetBackgroundColor() const
   return GetImplementation(*this).GetBackgroundColor();
 }
 
+Any SceneHolder::GetNativeHandle() const
+{
+  return GetImplementation(*this).GetNativeHandle();
+}
+
 void SceneHolder::FeedTouchPoint( Dali::TouchPoint& point, int timeStamp )
 {
   Integration::Point convertedPoint( point );
@@ -101,6 +106,11 @@ void SceneHolder::FeedKeyEvent( Dali::KeyEvent& keyEvent )
   GetImplementation(*this).FeedKeyEvent( convertedEvent );
 }
 
+SceneHolder SceneHolder::Get( Actor actor )
+{
+  return Internal::Adaptor::SceneHolder::Get( actor );
+}
+
 }// Integration
 
 } // Dali
index 59a2055..4881d22 100644 (file)
@@ -150,6 +150,14 @@ public:
    */
   void FeedKeyEvent( Dali::KeyEvent& keyEvent );
 
+  /**
+   * @brief Retrieve the SceneHolder that the given actor is added to.
+   *
+   * @param[in] actor The actor
+   * @return The SceneHolder the actor is added to or an empty handle if the actor is not added to any SceneHolder.
+   */
+  static SceneHolder Get( Actor actor );
+
 public: // Not intended for application developers
 
   /**
index d42eff5..868345d 100755 (executable)
@@ -799,6 +799,24 @@ Any Adaptor::GetNativeWindowHandle()
   return mWindows.front()->GetNativeHandle();
 }
 
+Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
+{
+  Any nativeWindowHandle;
+
+  Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
+
+  for( auto sceneHolder : mWindows )
+  {
+    if ( scene == sceneHolder->GetScene() )
+    {
+      nativeWindowHandle = sceneHolder->GetNativeHandle();
+      break;
+    }
+  }
+
+  return nativeWindowHandle;
+}
+
 Any Adaptor::GetGraphicsDisplay()
 {
   Any display;
index a716bea..99e4a0c 100755 (executable)
@@ -345,6 +345,14 @@ public:
   Any GetNativeWindowHandle();
 
   /**
+   * @brief Retrieve native window handle that the given actor is added to.
+   *
+   * @param[in] actor The actor
+   * @return native window handle
+   */
+  Any GetNativeWindowHandle( Dali::Actor actor );
+
+  /**
    * Get the native display associated with the graphics backend
    *
    * @return A handle to the native display
index 9b300bf..73fe2b3 100755 (executable)
@@ -161,6 +161,11 @@ Any Adaptor::GetNativeWindowHandle()
   return mImpl->GetNativeWindowHandle();
 }
 
+Any Adaptor::GetNativeWindowHandle( Actor actor )
+{
+  return mImpl->GetNativeWindowHandle( actor );
+}
+
 Any Adaptor::GetGraphicsDisplay()
 {
   return mImpl->GetGraphicsDisplay();
index a231f3d..f000748 100755 (executable)
@@ -32,7 +32,7 @@ namespace InputMethodContextFactory
 
 // Factory function creating new InputMethodContext
 // Symbol exists but may be overriden during linking
-InputMethodContextPtr CreateInputMethodContext();
+InputMethodContextPtr CreateInputMethodContext( Dali::Actor actor );
 
 }
 }
index 5ca15af..d145b30 100755 (executable)
@@ -28,9 +28,9 @@ namespace Internal
 namespace Adaptor
 {
 
-InputMethodContextPtr InputMethodContext::New()
+InputMethodContextPtr InputMethodContext::New( Dali::Actor actor )
 {
-  return Dali::Internal::Adaptor::InputMethodContextFactory::CreateInputMethodContext();
+  return Dali::Internal::Adaptor::InputMethodContextFactory::CreateInputMethodContext( actor );
 }
 
 const std::string& InputMethodContext::GetSurroundingText() const
index 33ab2a6..1527cc3 100755 (executable)
@@ -19,6 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/object/base-object.h>
 #include <dali/integration-api/events/key-event-integ.h>
@@ -61,7 +62,7 @@ public:
   /**
    * Create a new input method context instance.
    */
-  static InputMethodContextPtr New();
+  static InputMethodContextPtr New( Dali::Actor actor );
 
   /**
    * Initialize the object.
index 9615886..a30e996 100755 (executable)
@@ -31,9 +31,9 @@ namespace InputMethodContextFactory
 {
 
 // InputMethodContext Factory to be implemented by the platform
-InputMethodContextPtr CreateInputMethodContext()
+InputMethodContextPtr CreateInputMethodContext( Dali::Actor actor )
 {
-  return Dali::Internal::Adaptor::InputMethodContextEcoreWl::New();
+  return Dali::Internal::Adaptor::InputMethodContextEcoreWl::New( actor );
 }
 
 }
index 3abaf47..73b1a43 100755 (executable)
@@ -35,6 +35,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor.h>
+#include <dali/integration-api/scene-holder.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>
@@ -97,6 +98,8 @@ 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)
 {
@@ -268,33 +271,41 @@ void CommitContent( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
   }
 }
 
+int GetWindowIdFromActor( Dali::Actor actor )
+{
+  int windowId = kUninitializedWindowId;
+
+  if( actor.OnStage() )
+  {
+    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 +318,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.OnStageSignal().Connect( this, &InputMethodContextEcoreWl::OnStaged );
 }
 
 InputMethodContextEcoreWl::~InputMethodContextEcoreWl()
@@ -333,6 +347,11 @@ 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 +359,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" );
   }
 }
 
@@ -722,11 +727,14 @@ 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)));
+  }
 }
 
 Dali::InputMethodContext::TextDirection InputMethodContextEcoreWl::GetTextDirection()
@@ -1196,6 +1204,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
index 3d2e170..ba3fdf8 100755 (executable)
@@ -40,16 +40,17 @@ namespace Internal
 namespace Adaptor
 {
 
-class InputMethodContextEcoreWl : public Dali::Internal::Adaptor::InputMethodContext
+class InputMethodContextEcoreWl : public Dali::Internal::Adaptor::InputMethodContext, public Dali::ConnectionTracker
 {
 public:
 
   /**
    * @brief Creates a new InputMethodContext handle
    *
+   * @param[in] actor The actor that uses the new InputMethodContext instance.
    * @return InputMethodContext pointer
    */
-  static InputMethodContextPtr New();
+  static InputMethodContextPtr New( Dali::Actor actor );
 
   /**
    * @brief Initializes member data.
@@ -300,11 +301,16 @@ private:
    */
   Ecore_IMF_Keyboard_Locks EcoreInputModifierToEcoreIMFLock( unsigned int modifier );
 
+  /**
+   * Called when the binded actor is added to a window.
+   */
+  void OnStaged( Dali::Actor actor );
+
 private:
   /**
    * @brief Constructor.
    */
-  explicit InputMethodContextEcoreWl();
+  explicit InputMethodContextEcoreWl( Dali::Actor actor );
 
 protected:
   /**
@@ -328,7 +334,9 @@ private:
   bool mIdleCallbackConnected:1;             ///< Whether the idle callback is already connected.
 
   std::vector<Dali::Integration::KeyEvent> mKeyEvents; ///< Stores key events to be sent from idle call-back.
-  InputMethodOptions        mOptions;
+  InputMethodOptions mOptions;
+
+  int mWindowId;
 };
 
 
index be7b442..fb0fe9e 100755 (executable)
@@ -31,9 +31,9 @@ namespace InputMethodContextFactory
 {
 
 // InputMethodContext Factory to be implemented by the platform
-InputMethodContextPtr CreateInputMethodContext()
+InputMethodContextPtr CreateInputMethodContext( Dali::Actor actor )
 {
-  return Dali::Internal::Adaptor::InputMethodContextX::New();
+  return Dali::Internal::Adaptor::InputMethodContextX::New( actor );
 }
 
 }
index 60a5446..6a19a01 100755 (executable)
@@ -122,31 +122,13 @@ void ImfDeleteSurrounding( void *data, Ecore_IMF_Context *imfContext, void *even
 
 } // unnamed namespace
 
-InputMethodContextPtr InputMethodContextX::New()
+InputMethodContextPtr InputMethodContextX::New( Dali::Actor actor )
 {
   InputMethodContextPtr manager;
 
-  if ( Adaptor::IsAvailable() )
+  if( actor && Dali::Adaptor::IsAvailable() )
   {
-    // Create instance and register singleton only if the adaptor is available
-    Adaptor& adaptorImpl( Adaptor::GetImplementation( Adaptor::Get() ) );
-    Any nativeWindow = adaptorImpl.GetNativeWindowHandle();
-
-    // The Ecore_X_Window needs to use the InputMethodContext.
-    // Only when the render surface is window, we can get the Ecore_X_Window.
-    Ecore_X_Window ecoreXwin( AnyCast<Ecore_X_Window>(nativeWindow) );
-    if (ecoreXwin)
-    {
-      // If we fail to get Ecore_X_Window, we can't use the InputMethodContext correctly.
-      // Thus you have to call "ecore_imf_context_client_window_set" somewhere.
-      // In EvasPlugIn, this function is called in EvasPlugin::ConnectEcoreEvent().
-
-      manager = new InputMethodContextX( ecoreXwin );
-    }
-    else
-    {
-      DALI_LOG_ERROR("Failed to get native window handle\n");
-    }
+    manager = new InputMethodContextX( actor );
   }
 
   return manager;
@@ -160,15 +142,17 @@ void InputMethodContextX::Finalize()
   DeleteContext();
 }
 
-InputMethodContextX::InputMethodContextX( Ecore_X_Window ecoreXwin )
+InputMethodContextX::InputMethodContextX( Dali::Actor actor )
 : mIMFContext(),
-  mEcoreXwin( ecoreXwin ),
+  mEcoreXwin( 0 ),
   mIMFCursorPosition( 0 ),
   mSurroundingText(),
   mRestoreAfterFocusLost( false ),
   mIdleCallbackConnected( false )
 {
   ecore_imf_init();
+
+  actor.OnStageSignal().Connect( this, &InputMethodContextX::OnStaged );
 }
 
 InputMethodContextX::~InputMethodContextX()
@@ -179,15 +163,20 @@ InputMethodContextX::~InputMethodContextX()
 
 void InputMethodContextX::Initialize()
 {
-  CreateContext( mEcoreXwin );
+  CreateContext();
   ConnectCallbacks();
   VirtualKeyboard::ConnectCallbacks( mIMFContext );
 }
 
-void InputMethodContextX::CreateContext( Ecore_X_Window ecoreXwin )
+void InputMethodContextX::CreateContext()
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextX::CreateContext\n" );
 
+  if( !mEcoreXwin )
+  {
+    return;
+  }
+
   const char *contextId = ecore_imf_context_default_id_get();
   if( contextId )
   {
@@ -195,10 +184,7 @@ void InputMethodContextX::CreateContext( Ecore_X_Window ecoreXwin )
 
     if( mIMFContext )
     {
-      if( ecoreXwin )
-      {
-        ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast<void*>( ecoreXwin ) );
-      }
+      ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast<void*>( mEcoreXwin ) );
     }
     else
     {
@@ -935,6 +921,20 @@ Ecore_IMF_Keyboard_Locks InputMethodContextX::EcoreInputModifierToEcoreIMFLock(
     return static_cast<Ecore_IMF_Keyboard_Locks>( lock );
 }
 
+void InputMethodContextX::OnStaged( Dali::Actor actor )
+{
+  Ecore_X_Window ecoreXwin( AnyCast< Ecore_X_Window >( Dali::Integration::SceneHolder::Get( actor ).GetNativeHandle() ) );
+
+  if( mEcoreXwin != ecoreXwin )
+  {
+    mEcoreXwin = ecoreXwin;
+
+    // Reset
+    Finalize();
+    Initialize();
+  }
+}
+
 } // Adaptor
 
 } // Internal
index 894d0f1..43fe822 100755 (executable)
@@ -39,21 +39,22 @@ namespace Internal
 namespace Adaptor
 {
 
-class InputMethodContextX : public Dali::Internal::Adaptor::InputMethodContext
+class InputMethodContextX : public Dali::Internal::Adaptor::InputMethodContext, public Dali::ConnectionTracker
 {
 public:
   /**
    * @brief Creates a new InputMethodContext handle
    *
+   * @param[in] actor The actor that uses the new InputMethodContext instance.
    * @return InputMethodContext pointer
    */
-  static InputMethodContextPtr New();
+  static InputMethodContextPtr New( Dali::Actor actor );
 
   /**
    * Constructor
-   * @param[in] ecoreXwin, The window is created by application.
+   * @param[in] actor The actor that uses the new InputMethodContext instance.
    */
-  explicit InputMethodContextX( Ecore_X_Window ecoreXwin );
+  explicit InputMethodContextX( Dali::Actor actor );
 
 public:
 
@@ -265,9 +266,8 @@ public:
 private:
   /**
    * Context created the first time and kept until deleted.
-   * @param[in] ecoreXwin, The window is created by application.
    */
-  void CreateContext( Ecore_X_Window ecoreXwin );
+  void CreateContext();
 
   /**
    * @copydoc Dali::InputMethodContext::DeleteContext()
@@ -307,6 +307,11 @@ private:
    */
   Ecore_IMF_Keyboard_Locks EcoreInputModifierToEcoreIMFLock( unsigned int modifier );
 
+  /**
+   * Called when the binded actor is added to a window.
+   */
+  void OnStaged( Dali::Actor actor );
+
 public:
 
   /**
index 817dacb..131bbb5 100755 (executable)
@@ -31,9 +31,9 @@ namespace InputMethodContextFactory
 {
 
 // InputMethodContext Factory to be implemented by the platform
-InputMethodContextPtr CreateInputMethodContext()
+InputMethodContextPtr CreateInputMethodContext( Dali::Actor actor )
 {
-  return Dali::Internal::Adaptor::InputMethodContextWin::New();
+  return Dali::Internal::Adaptor::InputMethodContextWin::New( actor );
 }
 
 }
index ee3ff2b..5df001d 100755 (executable)
@@ -41,27 +41,13 @@ namespace Internal
 namespace Adaptor\r
 {\r
 \r
-InputMethodContextPtr InputMethodContextWin::New()\r
+InputMethodContextPtr InputMethodContextWin::New( Dali::Actor actor )\r
 {\r
   InputMethodContextPtr manager;\r
 \r
-  if ( Adaptor::IsAvailable() )\r
+  if ( actor && Adaptor::IsAvailable() )\r
   {\r
-    // Create instance and register singleton only if the adaptor is available\r
-    Adaptor& adaptorImpl( Adaptor::GetImplementation( Adaptor::Get() ) );\r
-    Any nativeWindow = adaptorImpl.GetNativeWindowHandle();\r
-\r
-    // The Win_Window_Handle needs to use the InputMethodContext.\r
-    // Only when the render surface is window, we can get the Win_Window_Handle.\r
-    WinWindowHandle winWindow( AnyCast<WinWindowHandle>(nativeWindow) );\r
-    if ( winWindow )\r
-    {\r
-      manager = new InputMethodContextWin( winWindow );\r
-    }\r
-    else\r
-    {\r
-      DALI_LOG_ERROR("Failed to get native window handle\n");\r
-    }\r
+    manager = new InputMethodContextWin( actor );\r
   }\r
 \r
   return manager;\r
@@ -71,13 +57,15 @@ void InputMethodContextWin::Finalize()
 {\r
 }\r
 \r
-InputMethodContextWin::InputMethodContextWin( WinWindowHandle winWindow )\r
-: mWin32Window( winWindow ),\r
+InputMethodContextWin::InputMethodContextWin( Dali::Actor actor )\r
+: mWin32Window( 0 ),\r
   mIMFCursorPosition( 0 ),\r
   mSurroundingText(),\r
   mRestoreAfterFocusLost( false ),\r
   mIdleCallbackConnected( false )\r
 {\r
+\r
+  actor.OnStageSignal().Connect( this, &InputMethodContextWin::OnStaged );\r
 }\r
 \r
 InputMethodContextWin::~InputMethodContextWin()\r
@@ -383,6 +371,20 @@ bool InputMethodContextWin::ProcessEventKeyUp( const KeyEvent& keyEvent )
   return eventHandled;\r
 }\r
 \r
+void InputMethodContextWin::OnStaged( Dali::Actor actor )\r
+{\r
+  WinWindowHandle winWindow( AnyCast< WinWindowHandle >( Dali::Integration::SceneHolder::Get( actor ).GetNativeHandle() ) );\r
+\r
+  if( mWin32Window != winWindow )\r
+  {\r
+    mWin32Window = winWindow;\r
+\r
+    // Reset\r
+    Finalize();\r
+    Initialize();\r
+  }\r
+}\r
+\r
 } // Adaptor\r
 \r
 } // Internal\r
index e1c1e33..a0eed9d 100755 (executable)
@@ -37,21 +37,22 @@ namespace Internal
 namespace Adaptor\r
 {\r
 \r
-class InputMethodContextWin : public Dali::Internal::Adaptor::InputMethodContext\r
+class InputMethodContextWin : public Dali::Internal::Adaptor::InputMethodContext, public Dali::ConnectionTracker\r
 {\r
 public:\r
   /**\r
    * @brief Creates a new InputMethodContext handle\r
    *\r
+   * @param[in] actor The actor that uses the new InputMethodContext instance.\r
    * @return InputMethodContext pointer\r
    */\r
-  static InputMethodContextPtr New();\r
+  static InputMethodContextPtr New( Dali::Actor actor );\r
 \r
   /**\r
    * Constructor\r
    * @param[in] win32Window, The window is created by application.\r
    */\r
-  explicit InputMethodContextWin( WinWindowHandle win32Window );\r
+  explicit InputMethodContextWin( Dali::Actor actor );\r
 \r
 public:\r
 \r
@@ -280,6 +281,11 @@ private:
    */\r
   bool ProcessEventKeyUp( const KeyEvent& keyEvent );\r
 \r
+  /**\r
+   * Called when the binded actor is added to a window.\r
+   */\r
+  void OnStaged( Dali::Actor actor );\r
+\r
 public:\r
 \r
   /**\r
index 4ecda0d..4411ffa 100644 (file)
@@ -694,7 +694,6 @@ Dali::Window Window::Get( Dali::Actor actor )
   return Dali::Window( windowImpl );
 }
 
-
 void Window::SetParent( Dali::Window& parent )
 {
   if ( DALI_UNLIKELY( parent ) )