Return finalized_content as surrounding text when focus lost 18/158518/5
authorJi-hoon Lee <dalton.lee@samsung.com>
Wed, 1 Nov 2017 10:43:42 +0000 (19:43 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Tue, 7 Nov 2017 00:47:39 +0000 (00:47 +0000)
Change-Id: Iaa2935c3502d4d75c8fdd049ef1d4b5ebbbe9178

16 files changed:
ism/extras/wayland_immodule/wayland_imcontext.c
ism/modules/panelagent/ecoresocket/ecore_socket_panel_agent_module.cpp
ism/modules/panelagent/wayland/isf_wsc_control.cpp
ism/modules/panelagent/wayland/isf_wsc_control.h
ism/modules/panelagent/wayland/isf_wsc_control_ui.cpp
ism/modules/panelagent/wayland/isf_wsc_control_ui.h
ism/modules/panelagent/wayland/wayland_panel_agent_module.cpp
ism/src/isf_info_manager.cpp
ism/src/isf_info_manager.h
ism/src/isf_message_queue.h
ism/src/isf_panel_agent_base.cpp
ism/src/isf_panel_agent_base.h
ism/src/isf_panel_agent_manager.cpp
ism/src/isf_panel_agent_manager.h
ism/src/scim_helper.cpp
ism/src/scim_trans_commands.h

index d613512..c5e80f5 100644 (file)
@@ -1308,9 +1308,19 @@ set_focus(Ecore_IMF_Context *ctx)
 static void
 set_focus_out(Ecore_IMF_Context *ctx)
 {
+    char *surrounding = NULL;
+    int cursor_pos = 0;
+
     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
     if (!imcontext || !imcontext->input) return;
 
+    if (ecore_imf_context_surrounding_get(ctx, &surrounding, &cursor_pos)) {
+        if (surrounding) {
+            wl_text_input_finalize_content(imcontext->text_input, surrounding, cursor_pos);
+            free(surrounding);
+        }
+    }
+
     // deactivate
     if (imcontext->text_input)
         wl_text_input_deactivate(imcontext->text_input,
index bb74bb0..8d6c6cf 100644 (file)
@@ -812,7 +812,7 @@ private:
         m_send_trans.write_to_socket(client_socket);
     }
 
-    void set_helper_mime_type (int client, uint32 context, const String& uuid, String& mime_type) {
+    void set_helper_mime_type(int client, uint32 context, const String& uuid, String& mime_type) {
         LOGD ("client id:%d\n", client);
 
         Socket client_socket(client);
@@ -825,6 +825,20 @@ private:
         m_send_trans.write_to_socket(client_socket);
     }
 
+    void finalize_content_helper(int client, uint32 context, const String& uuid, String& text, uint32& cursor_pos) {
+        LOGD("client id:%d\n", client);
+
+        Socket client_socket(client);
+        m_send_trans.clear();
+        m_send_trans.put_command(SCIM_TRANS_CMD_REPLY);
+        m_send_trans.put_data(context);
+        m_send_trans.put_data(uuid);
+        m_send_trans.put_command(ISM_TRANS_CMD_FINALIZE_CONTENT);
+        m_send_trans.put_data(text);
+        m_send_trans.put_data(cursor_pos);
+        m_send_trans.write_to_socket(client_socket);
+    }
+
     bool process_key_event(int client, uint32 context, const String& uuid, KeyEvent& key, uint32 serial) {
         LOGD ("client id:%d\n", client);
 
index 72d0579..aa2bf34 100644 (file)
@@ -224,6 +224,12 @@ int _isf_wsc_context_input_panel_mime_type_accept_set (int context, const char *
     g_info_manager->set_ise_mime_type (get_panel_client_id (), String (mime_type));
     return 0;
 }
+
+int _isf_wsc_context_input_panel_finalize_content (int context, const char *text, int cursor_pos)
+{
+    g_info_manager->finalize_content (get_panel_client_id (), String (text), cursor_pos);
+    return 0;
+}
 /*
 vi:ts=4:expandtab:nowrap
 */
index 6192683..f127e26 100644 (file)
@@ -66,6 +66,7 @@ extern "C"
     int _isf_wsc_context_process_input_device_event(int context, int type, const void* data, int len);
     int _isf_wsc_context_input_panel_prediction_hint_set (int context, const char *prediction_hint);
     int _isf_wsc_context_input_panel_mime_type_accept_set (int context, const char *mime_type);
+    int _isf_wsc_context_input_panel_finalize_content (int context, const char *text, int cursor_pos);
 
 #ifdef __cplusplus
 }
index 2ea5b14..9743023 100644 (file)
@@ -303,3 +303,8 @@ void isf_wsc_context_input_panel_mime_type_accept_set (WSCContextISF *ctx, const
 {
     _isf_wsc_context_input_panel_mime_type_accept_set (_get_context_id(ctx), mime_type);
 }
+
+void isf_wsc_context_input_panel_finalize_content (WSCContextISF *ctx, const char *text, int cursor_pos)
+{
+    _isf_wsc_context_input_panel_finalize_content (_get_context_id(ctx), text, cursor_pos);
+}
index 5a742f7..21062b2 100644 (file)
@@ -56,6 +56,7 @@ extern "C"
     void isf_wsc_context_process_input_device_event (WSCContextISF *ctx, uint32_t type, const char *data, uint32_t len);
     void isf_wsc_context_input_panel_prediction_hint_set (WSCContextISF *ctx, const char *prediction_hint);
     void isf_wsc_context_input_panel_mime_type_accept_set (WSCContextISF *ctx, const char *mime_type);
+    void isf_wsc_context_input_panel_finalize_content (WSCContextISF *ctx, const char *text, int cursor_pos);
 
 #ifdef __cplusplus
 }
index 2abd7c7..959e409 100644 (file)
@@ -492,6 +492,17 @@ _wsc_im_ctx_mime_type (void *data, struct wl_input_method_context *im_ctx, const
     isf_wsc_context_input_panel_mime_type_accept_set (wsc_ctx, mime_type);
 }
 
+static void
+_wsc_im_ctx_finalized_content (void *data, struct wl_input_method_context *im_ctx, const char *text, uint32_t cursor_pos)
+{
+    WSCContextISF *wsc_ctx = (WSCContextISF*)data;
+
+    SECURE_LOGD ("im_context = %p, text = %s, cursor_pos = %d\n", im_ctx, text, cursor_pos);
+    if (!wsc_ctx) return;
+
+    isf_wsc_context_input_panel_finalize_content (wsc_ctx, text, cursor_pos);
+}
+
 static const struct wl_input_method_context_listener wsc_im_context_listener = {
      _wsc_im_ctx_reset,
      _wsc_im_ctx_content_type,
@@ -507,7 +518,8 @@ static const struct wl_input_method_context_listener wsc_im_context_listener = {
      _wsc_im_ctx_filter_key_event,
      _wsc_im_ctx_capital_mode,
      _wsc_im_ctx_prediction_hint,
-     _wsc_im_ctx_mime_type
+     _wsc_im_ctx_mime_type,
+     _wsc_im_ctx_finalized_content
 };
 
 #if ENABLE_GRAB_KEYBOARD
index d7baf37..476493b 100644 (file)
@@ -1383,6 +1383,23 @@ public:
         return false;
     }
 
+    bool finalize_content_helper (const String& uuid, String text, uint32 cursor_pos) {
+        HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
+
+        if (it != m_helper_client_index.end ()) {
+            int client;
+            uint32 context;
+            uint32 ctx;
+            get_focused_context (client, context);
+            ctx = get_helper_ic (client, context);
+            LOGD ("Send ISM_TRANS_CMD_FINALIZE_CONTENT message");
+            m_panel_agent_manager.finalize_content_helper (it->second.id, ctx, uuid, text, cursor_pos);
+            return true;
+        }
+
+        return false;
+    }
+
     //ISM_TRANS_CMD_SHOW_ISF_CONTROL
     void show_isf_panel (int client_id) {
         LOGD ("");
@@ -2084,6 +2101,14 @@ public:
             set_helper_mime_type (m_current_helper_uuid, mime_type);
     }
 
+    //ISM_TRANS_CMD_FINALIZE_CONTENT
+    void finalize_content (int client_id, String text, uint32 cursor_pos) {
+        SCIM_DEBUG_MAIN (4) << "InfoManager::finalize_content ()\n";
+        LOGD ("");
+        if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode || m_current_helper_option & ISM_HELPER_PROCESS_KEYBOARD_KEYEVENT)
+            finalize_content_helper (m_current_helper_uuid, text, cursor_pos);
+    }
+
     //ISM_TRANS_CMD_EXPAND_CANDIDATE
     void expand_candidate () {
         LOGD ("");
@@ -4925,6 +4950,12 @@ void InfoManager::set_ise_mime_type (int client_id, String mime_type)
     m_impl->set_ise_mime_type (client_id, mime_type);
 }
 
+//ISM_TRANS_CMD_FINALIZE_CONTENT
+void InfoManager::finalize_content (int client_id, String text, uint32 cursor_pos)
+{
+    m_impl->finalize_content (client_id, text, cursor_pos);
+}
+
 //ISM_TRANS_CMD_EXPAND_CANDIDATE
 void InfoManager::expand_candidate ()
 {
index cbe1ec6..9f50a0b 100644 (file)
@@ -744,6 +744,9 @@ public:
     //ISM_TRANS_CMD_SET_MIME_TYPE
     void set_ise_mime_type (int client_id, String mime_type);
 
+    //ISM_TRANS_CMD_FINALIZE_CONTENT
+    void finalize_content(int client_id, String text, uint32 cursor_pos);
+
     //ISM_TRANS_CMD_EXPAND_CANDIDATE
     void expand_candidate ();
 
index c75d7d6..52ae75b 100644 (file)
@@ -730,6 +730,20 @@ protected:
     String m_mime_type;
 };
 
+/* ISM_TRANS_CMD_FINALIZE_CONTENT */
+class MessageItemFinalizeContent : public MessageItemHelper
+{
+public:
+    MessageItemFinalizeContent() : m_cursor_pos(0) {}
+    virtual ~MessageItemFinalizeContent() {}
+
+    String& get_text_ref() { return m_text; }
+    uint32& get_cursor_pos_ref() { return m_cursor_pos; }
+protected:
+    String m_text;
+    uint32 m_cursor_pos;
+};
+
 template <typename T>
 inline T*
 alloc_message() /* We could use memory pool in the future for performance enhancement */
@@ -1692,6 +1706,21 @@ public:
                     }
                     break;
                 }
+                case ISM_TRANS_CMD_FINALIZE_CONTENT:
+                {
+                    MessageItemFinalizeContent *message = alloc_message<MessageItemFinalizeContent>();
+                    if (message) {
+                        message->get_command_ref() = cmd;
+                        if (transaction.get_data(message->get_text_ref()) &&
+                            transaction.get_data(message->get_cursor_pos_ref())) {
+                            m_list_messages.push_back(message);
+                        } else {
+                            LOGW("wrong format of transaction\n");
+                            dealloc_message<MessageItemFinalizeContent>(message);
+                        }
+                    }
+                    break;
+                }
             }
         }
 
index 5d14a87..ab0d842 100644 (file)
@@ -321,6 +321,11 @@ void PanelAgentBase::set_helper_mime_type (int client, uint32 context, const Str
     LOGW ("not implemented for %s", m_name.c_str ());
 }
 
+void PanelAgentBase::finalize_content_helper (int client, uint32 context, const String& uuid, String& text, uint32& cursor_pos)
+{
+    LOGW("not implemented for %s", m_name.c_str());
+}
+
 bool PanelAgentBase::process_key_event (int client, uint32 context, const String& uuid, KeyEvent& key, uint32 serial)
 {
     LOGW ("not implemented for %s", m_name.c_str ());
index 2d262be..fb35a6d 100644 (file)
@@ -503,6 +503,15 @@ public:
     virtual void set_helper_mime_type (int client, uint32 context, const String& uuid, String& mime_type);
 
     /**
+     * @brief finalize_content_helper.
+     *
+     * @param
+     *
+     * @return none.
+     */
+    virtual void finalize_content_helper (int client, uint32 context, const String& uuid, String& text, uint32& cursor_pos);
+
+    /**
      * @brief process_key_event.
      *
      * @param
index d6e1978..43a6482 100644 (file)
@@ -522,6 +522,14 @@ void PanelAgentManager::set_helper_mime_type (int id, uint32 context_id, const S
         _p->set_helper_mime_type (id, context_id, uuid, mime_type);
 }
 
+void PanelAgentManager::finalize_content_helper (int id, uint32 context_id, const String& uuid, String& text, uint32& cursor_pos)
+{
+    PanelAgentPointer _p = m_impl->get_panel_agent_by_id(id);
+
+    if (!_p.null())
+        _p->finalize_content_helper (id, context_id, uuid, text, cursor_pos);
+}
+
 bool PanelAgentManager::process_key_event (int id, uint32 context_id, const String& uuid, KeyEvent& key, uint32 serial)
 {
     PanelAgentPointer _p = m_impl->get_panel_agent_by_id (id);
index 506c980..fa767d0 100644 (file)
@@ -310,6 +310,7 @@ public:
     void set_helper_keyboard_mode (int client, uint32 context, const String& uuid, uint32& mode);
     void set_helper_prediction_hint (int client, uint32 context, const String& uuid, String& prediction_hint);
     void set_helper_mime_type (int client, uint32 context, const String& uuid, String& mime_type);
+    void finalize_content_helper (int client, uint32 context, const String& uuid, String& text, uint32& cursor_pos);
     bool process_key_event (int client, uint32 context, const String& uuid, KeyEvent& key, uint32 serial);
     bool get_helper_geometry (int client, uint32 context, String& uuid, _OUT_ struct rectinfo& info);
     void get_helper_imdata (int client, uint32 context, String& uuid, _OUT_ char** imdata, _OUT_ size_t& len);
index 4e53df4..3abea17 100644 (file)
@@ -163,6 +163,9 @@ public:
     uint32 layout;
     bool ise_show_flag;
     bool hw_keyboard_mode;
+    bool ise_focus_flag;
+    char* finalized_text;
+    uint32 finalized_cursor_pos;
 
     HelperAgentSignalVoid           signal_exit;
     HelperAgentSignalVoid           signal_attach_input_context;
@@ -231,7 +234,8 @@ public:
     HelperAgentImpl (HelperAgent* thiz) : magic(0), magic_active(0), timeout(-1), focused_ic ((uint32) -1), thiz (thiz),
         surrounding_text (NULL), selection_text (NULL), cursor_pos (0),
         need_update_surrounding_text (0), need_update_selection_text (0),
-        layout (0), ise_show_flag (false), hw_keyboard_mode (false) {
+        layout (0), ise_show_flag (false), hw_keyboard_mode (false), ise_focus_flag (false),
+        finalized_text(NULL), finalized_cursor_pos(0) {
     }
 
     ~HelperAgentImpl () {
@@ -242,6 +246,9 @@ public:
         if (surrounding_text != NULL)
             free (surrounding_text);
 
+        if (finalized_text != NULL)
+            free(finalized_text);
+
         if (selection_text != NULL)
             free (selection_text);
 
@@ -1000,6 +1007,7 @@ HelperAgent::handle_message (MessageItem *message)
         case SCIM_TRANS_CMD_FOCUS_OUT:
         {
             MessageItemFocusOut *subclass = static_cast<MessageItemFocusOut*>(message);
+            m_impl->ise_focus_flag = false;
             m_impl->signal_focus_out (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
             m_impl->focused_ic = (uint32) -1;
             if (!m_impl->si.null ()) m_impl->si->focus_out();
@@ -1010,8 +1018,13 @@ HelperAgent::handle_message (MessageItem *message)
         case SCIM_TRANS_CMD_FOCUS_IN:
         {
             MessageItemFocusIn *subclass = static_cast<MessageItemFocusIn*>(message);
+            m_impl->ise_focus_flag = true;
             m_impl->signal_focus_in (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
             m_impl->focused_ic = subclass->get_ic_ref();
+            if (m_impl->finalized_text != NULL)
+                free(m_impl->finalized_text);
+            m_impl->finalized_text = NULL;
+            m_impl->finalized_cursor_pos = 0;
             if (!m_impl->si.null ()) m_impl->si->focus_in();
             break;
         }
@@ -1440,6 +1453,17 @@ HelperAgent::handle_message (MessageItem *message)
             }
             break;
         }
+        case ISM_TRANS_CMD_FINALIZE_CONTENT:
+        {
+            MessageItemFinalizeContent *subclass = static_cast<MessageItemFinalizeContent*>(message);
+            if (m_impl) {
+                if (m_impl->finalized_text != NULL)
+                    free(m_impl->finalized_text);
+                m_impl->finalized_text = strdup(subclass->get_text_ref().c_str());
+                m_impl->finalized_cursor_pos = subclass->get_cursor_pos_ref();
+            }
+            break;
+        }
         default:
             break;
     }
@@ -2028,35 +2052,50 @@ HelperAgent::get_surrounding_text (int maxlen_before, int maxlen_after, String &
     if (!m_impl->socket_active.is_connected ())
         return;
 
-    m_impl->send.clear ();
-    m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
-    m_impl->send.put_data (m_impl->magic_active);
-    m_impl->send.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
-    m_impl->send.put_data ("");
-    m_impl->send.put_data (maxlen_before);
-    m_impl->send.put_data (maxlen_after);
-    m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
-    if (m_impl->surrounding_text) {
-        free (m_impl->surrounding_text);
-        m_impl->surrounding_text = NULL;
-    }
+    if (!m_impl->ise_focus_flag) {
+        if (m_impl->finalized_text) {
+            String buffer = m_impl->finalized_text;
+            cursor = m_impl->finalized_cursor_pos;
+            int pos = cursor - maxlen_before;
+            if (pos < 0) pos = 0;
+            int len = maxlen_after + (cursor - pos);
+            if (len < 0) len = INT_MAX;
+            text = buffer.substr (pos, len);
+        } else {
+            text.clear ();
+            cursor = 0;
+        }
+    } else {
+        m_impl->send.clear();
+        m_impl->send.put_command(SCIM_TRANS_CMD_REQUEST);
+        m_impl->send.put_data(m_impl->magic_active);
+        m_impl->send.put_command(SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
+        m_impl->send.put_data("");
+        m_impl->send.put_data(maxlen_before);
+        m_impl->send.put_data(maxlen_after);
+        m_impl->send.write_to_socket(m_impl->socket_active, m_impl->magic_active);
+        if (m_impl->surrounding_text) {
+            free(m_impl->surrounding_text);
+            m_impl->surrounding_text = NULL;
+        }
 
-    const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
-    /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT message */
-    if (wait_for_message(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
-        MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT);
-        handle_message(message);
-        message_queue.remove_message(message);
+        const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
+        /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT message */
+        if (wait_for_message(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
+            MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT);
+            handle_message(message);
+            message_queue.remove_message(message);
 
-        if (m_impl->surrounding_text) {
-            text = m_impl->surrounding_text;
-            cursor = m_impl->cursor_pos;
+            if (m_impl->surrounding_text) {
+                text = m_impl->surrounding_text;
+                cursor = m_impl->cursor_pos;
+            }
         }
-    }
 
-    if (m_impl->surrounding_text) {
-        free (m_impl->surrounding_text);
-        m_impl->surrounding_text = NULL;
+        if (m_impl->surrounding_text) {
+            free(m_impl->surrounding_text);
+            m_impl->surrounding_text = NULL;
+        }
     }
 }
 
index 3b65925..32e52cb 100644 (file)
@@ -671,6 +671,7 @@ const int ISM_TRANS_CMD_RESUME_ISE_OPTION_WINDOW          = 1127;
 const int ISM_TRANS_CMD_SET_KEYBOARD_MODE                 = 1128;
 const int ISM_TRANS_CMD_SET_PREDICTION_HINT               = 1129;
 const int ISM_TRANS_CMD_SET_MIME_TYPE                     = 1130;
+const int ISM_TRANS_CMD_FINALIZE_CONTENT                  = 1131;
 
 /* ISE/Panel to IMControl */
 const int ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT          = 1151;