From 29135b6e766d9d0a0c3cf5f6a4f5f3ef3f1315fc Mon Sep 17 00:00:00 2001 From: "prathmesh.m" Date: Fri, 29 Mar 2013 16:45:38 +0900 Subject: [PATCH] Fixed caret selection issue in inputbox [Title] Fixed carret selection issue in inputbox [Issue#] N/A [Problem] Caret was set at the end of text field even after long press in between the input box. [Cause] Invalid points were passed when the touch point was on the border of the inputbox. Focused frame points were passed. [Solution] Handled the border cases and set the proper touch point. Set the mainframe point with the difference of rect and focused frame point Change-Id: Id3cd249c52e47764c34e28eee82125e07f219c54 --- .../WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp | 66 ++++++++++++---------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp index e6afc26..8ea6028 100755 --- a/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp +++ b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp @@ -454,13 +454,13 @@ void WebPage::setComposition(const String& compositionString, const VectorfocusController()->focusedOrMainFrame(); if (!frame) return false; - WebCore::FrameSelection* controller = frame->selection(); + FrameSelection* controller = frame->selection(); if (!controller) return false; @@ -468,24 +468,24 @@ bool WebPage::setCaretPosition(const WebCore::IntPoint& pos) if (!frameView) return false; - WebCore::IntPoint point = m_page->mainFrame()->view()->windowToContents(pos); - WebCore::HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, /*allowShadowContent*/ true, /*ignoreClipping*/ true); + IntPoint point = m_page->mainFrame()->view()->windowToContents(pos); + HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, /*allowShadowContent*/ true, /*ignoreClipping*/ true); if (result.scrollbar()) return false; - WebCore::Node* innerNode = result.innerNode(); + Node* innerNode = result.innerNode(); if (!innerNode || !innerNode->renderer()) return false; - WebCore::VisiblePosition visiblePos; + VisiblePosition visiblePos; // we check if content is richly editable - because those input field behave other than plain text ones // sometimes they may consists a node structure and they need special approach if (innerNode->rendererIsRichlyEditable()) { // point gets inner node local coordinates point = flooredIntPoint(result.localPoint()); - WebCore::IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true); + IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true); // it is not the best way to do this, but it is not as slow and it works - so maybe in the future someone // will have a better idea how to solve it @@ -495,13 +495,13 @@ bool WebPage::setCaretPosition(const WebCore::IntPoint& pos) // all those getting nodes rects are needed to bypass WebCore's methods of positioning caret when user // is clicking outside a node - and cheat WebCore telling it that actually we clicked into input field // node, not outside of it - WebCore::Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode(); + Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode(); if (!deepInnerNode || !deepInnerNode->renderer()) return false; // so we get a base node rectange - WebCore::IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true); + IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true); // we modify our local point to adjust it to base node local coordinates point.move(rect.x() - deepNodeRect.x(), rect.y() - deepNodeRect.y()); @@ -521,35 +521,41 @@ bool WebPage::setCaretPosition(const WebCore::IntPoint& pos) if (!controller->isCaret() || !controller->caretRenderer()) return false; - const WebCore::Node* node = controller->start().deprecatedNode(); + const Node* node = controller->start().deprecatedNode(); if (!node || !node->renderer()) return false; - WebCore::IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true); + IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true); -// FIXME: The below codes should be updated to apply the positon of focusedFrame. -#if 0 + // The below wirtten code is not correct way to implement. Presntly the is no + // other working way. To be replaced by better logic // here we also cheat input field that we actually are just inside of if - if (point.x() < rect.x()) - point.setX(rect.x()); - else if (point.x() > rect.maxX()) - point.setX(rect.maxX()); + IntPoint focusedFramePoint = frame->view()->windowToContents(pos); + IntPoint oldFocusedFramePoint = focusedFramePoint; const int boundariesWidth = 2; - if (point.y() < rect.y() + boundariesWidth) - point.setY(rect.y() + boundariesWidth); - else if (point.y() >= rect.maxY() - boundariesWidth) - point.setY(rect.maxY() - boundariesWidth - 1); -#endif + if (focusedFramePoint.x() < rect.x()) + focusedFramePoint.setX(rect.x()); + else if (focusedFramePoint.x() > rect.maxX()) + focusedFramePoint.setX(rect.maxX()); + if (focusedFramePoint.y() < rect.y() + boundariesWidth) + focusedFramePoint.setY(rect.y() + boundariesWidth); + else if (focusedFramePoint.y() >= rect.maxY() - boundariesWidth) + focusedFramePoint.setY(rect.maxY() - boundariesWidth - 1); + + int diffX = focusedFramePoint.x() - oldFocusedFramePoint.x(); + int diffY = focusedFramePoint.y() - oldFocusedFramePoint.y(); + point.setX((point.x())+diffX); + point.setY((point.y())+diffY); // hit test with fake (adjusted) coordinates - WebCore::IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(point); - WebCore::HitTestResult newResult = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ true); + IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(point); + HitTestResult newResult = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ true); if (!newResult.isContentEditable()) return false; - WebCore::Node* newInnerNode = newResult.innerNode(); + Node* newInnerNode = newResult.innerNode(); if (!newInnerNode || !newInnerNode->renderer()) return false; @@ -561,25 +567,25 @@ bool WebPage::setCaretPosition(const WebCore::IntPoint& pos) } // create visible selection from visible position - WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos); - controller->setSelection(newSelection, WebCore::CharacterGranularity); + VisibleSelection newSelection = VisibleSelection(visiblePos); + controller->setSelection(newSelection, CharacterGranularity); // after setting selection caret blinking is suspended by default so we are unsuspedning it controller->setCaretBlinkingSuspended(false); return true; } -void WebPage::getCaretPosition(WebCore::IntRect& rect) +void WebPage::getCaretPosition(IntRect& rect) { Frame* frame = m_page->focusController()->focusedOrMainFrame(); if (!frame) return; - WebCore::FrameSelection* controller = frame->selection(); + FrameSelection* controller = frame->selection(); if (!controller) return; - WebCore::Node* node = controller->start().deprecatedNode(); + Node* node = controller->start().deprecatedNode(); if (!node || !node->renderer() || !node->isContentEditable()) return; -- 2.7.4