From: ANZ1217 Date: Mon, 8 Apr 2024 11:46:52 +0000 (+0900) Subject: Fix Crash when the InsertText event is executed multiple times between Relayout. X-Git-Tag: dali_2.3.19~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=233f2cb3eda10554b4364512ee5656cc428c4b89 Fix Crash when the InsertText event is executed multiple times between Relayout. When using IME, InsertText may be executed multiple times within one relayout. Fix the problem that length of the text cannot be calculated correctly. Change-Id: Id47f7bbacf90a098055fc7b6ae0d4931a9facde2 --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp index 6a3a84a..774cce1 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp @@ -1362,3 +1362,44 @@ int UtcDaliTextControllerDeleteSurroundings(void) END_TEST; } + +int UtcDaliTextControllerMultipleInsert(void) +{ + tet_infoline(" UtcDaliTextControllerMultipleInsert"); + ToolkitTestApplication application; + + // Creates a text controller. + ControllerPtr controller = Controller::New(); + + ConfigureTextField(controller); + + // Get the implementation of the text controller + Controller::Impl& mImpl = Controller::Impl::GetImplementation(*controller.Get()); + + DALI_TEST_EQUALS(EventData::INACTIVE, mImpl.mEventData->mState, TEST_LOCATION); + + InputMethodContext inputMethodContext = InputMethodContext::New(); + + // When maid thread is busy, multiple event might be executed. + InputMethodContext::EventData imfEvent1 = InputMethodContext::EventData(InputMethodContext::PRE_EDIT, "A", 0, 1); + InputMethodContext::EventData imfEvent2 = InputMethodContext::EventData(InputMethodContext::PRE_EDIT, "AAAAA", 0, 5); + controller->OnInputMethodContextEvent(inputMethodContext, imfEvent1); + controller->OnInputMethodContextEvent(inputMethodContext, imfEvent2); + + // Perform a relayout + const Size size(application.GetScene().GetSize()); + + application.SendNotification(); + application.Render(); + + controller->Relayout(size); + + std::string text; + controller->GetText(text); + + DALI_TEST_EQUALS("AAAAA", text, TEST_LOCATION); + + tet_result(TET_PASS); + + END_TEST; +} diff --git a/dali-toolkit/internal/text/controller/text-controller-event-handler.cpp b/dali-toolkit/internal/text/controller/text-controller-event-handler.cpp index 8044923..99cc227 100644 --- a/dali-toolkit/internal/text/controller/text-controller-event-handler.cpp +++ b/dali-toolkit/internal/text/controller/text-controller-event-handler.cpp @@ -768,13 +768,13 @@ bool Controller::EventHandler::DeleteEvent(Controller& controller, int keyCode) else if((controller.mImpl->mEventData->mPrimaryCursorPosition > 0) && (keyCode == Dali::DALI_KEY_BACKSPACE)) { // Remove the character before the current cursor position - removed = TextUpdater::RemoveText(controller, -1, 1, UPDATE_INPUT_STYLE); + removed = TextUpdater::RemoveText(controller, -1, 1, UPDATE_INPUT_STYLE, false); } else if((controller.mImpl->mEventData->mPrimaryCursorPosition < controller.mImpl->mModel->mLogicalModel->mText.Count()) && (keyCode == Dali::DevelKey::DALI_KEY_DELETE)) { // Remove the character after the current cursor position - removed = TextUpdater::RemoveText(controller, 0, 1, UPDATE_INPUT_STYLE); + removed = TextUpdater::RemoveText(controller, 0, 1, UPDATE_INPUT_STYLE, false); } if(removed) @@ -825,7 +825,8 @@ InputMethodContext::CallbackData Controller::EventHandler::OnInputMethodContextE const bool textDeleted = TextUpdater::RemoveText(controller, inputMethodContextEvent.cursorOffset, inputMethodContextEvent.numberOfChars, - DONT_UPDATE_INPUT_STYLE); + DONT_UPDATE_INPUT_STYLE, + false); if(textDeleted) { diff --git a/dali-toolkit/internal/text/controller/text-controller-text-updater.cpp b/dali-toolkit/internal/text/controller/text-controller-text-updater.cpp index 2ceee77..59da80a 100644 --- a/dali-toolkit/internal/text/controller/text-controller-text-updater.cpp +++ b/dali-toolkit/internal/text/controller/text-controller-text-updater.cpp @@ -208,7 +208,8 @@ void Controller::TextUpdater::InsertText(Controller& controller, const std::stri removedPrevious = RemoveText(controller, -static_cast(eventData->mPrimaryCursorPosition - eventData->mPreEditStartPosition), eventData->mPreEditLength, - DONT_UPDATE_INPUT_STYLE); + DONT_UPDATE_INPUT_STYLE, + true); eventData->mPrimaryCursorPosition = eventData->mPreEditStartPosition; eventData->mPreEditLength = 0u; @@ -495,7 +496,8 @@ bool Controller::TextUpdater::RemoveText( Controller& controller, int cursorOffset, int numberOfCharacters, - UpdateInputStyleType type) + UpdateInputStyleType type, + bool isDeletingPreEdit) { bool removed = false; bool removeAll = false; @@ -608,7 +610,10 @@ bool Controller::TextUpdater::RemoveText( if(removeAll) { impl.ClearPreEditFlag(); - textUpdateInfo.mNumberOfCharactersToAdd = 0; + if(!isDeletingPreEdit) + { + textUpdateInfo.mNumberOfCharactersToAdd = 0; + } } // Updates the text style runs by removing characters. Runs with no characters are removed. diff --git a/dali-toolkit/internal/text/controller/text-controller-text-updater.h b/dali-toolkit/internal/text/controller/text-controller-text-updater.h index 47403f6..319697f 100644 --- a/dali-toolkit/internal/text/controller/text-controller-text-updater.h +++ b/dali-toolkit/internal/text/controller/text-controller-text-updater.h @@ -63,9 +63,10 @@ struct Controller::TextUpdater * @param[in] cursorOffset Start position from the current cursor position to start deleting characters. * @param[in] numberOfCharacters The number of characters to delete from the cursorOffset. * @param[in] type Whether to update the input style. + * @param[in] isDeletingPreEdit Whether to remove pre-edit when inserting text. * @return True if the remove was successful. */ - static bool RemoveText(Controller& controller, int cursorOffset, int numberOfCharacters, UpdateInputStyleType type); + static bool RemoveText(Controller& controller, int cursorOffset, int numberOfCharacters, UpdateInputStyleType type, bool isDeletingPreEdit); /** * @brief Checks if text is selected and if so removes it.