From: SangYong Park Date: Fri, 10 May 2013 10:14:22 +0000 (+0900) Subject: Implement Focus UI X-Git-Tag: 2.2_release~19 X-Git-Url: http://review.tizen.org/git/?p=framework%2Fweb%2Fwebkit-efl.git;a=commitdiff_plain;h=6cfa0d1a8d21fcdb6851fdf7ff67ae713a416eb1 Implement Focus UI [Title] Implement Focus UI [Issue#] N/A [Problem] Focus UI is not supported. [Cause] N/A [Solution] N/A Change-Id: I9845408e0a104f7777db5271f1c55e412dfbcede --- diff --git a/Source/WebCore/page/FocusController.cpp b/Source/WebCore/page/FocusController.cpp index 8b4b414..d3ff2a6 100755 --- a/Source/WebCore/page/FocusController.cpp +++ b/Source/WebCore/page/FocusController.cpp @@ -60,11 +60,19 @@ #include "htmlediting.h" // For firstPositionInOrBeforeNode #include +#if ENABLE(TIZEN_FOCUS_UI) +#include "RenderLayer.h" +#endif + namespace WebCore { using namespace HTMLNames; using namespace std; +#if ENABLE(TIZEN_FOCUS_UI) +HashSet m_excludedCandidateSet; +#endif + static inline ComposedShadowTreeWalker walkerFrom(const Node* node) { return ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary); @@ -731,6 +739,96 @@ void FocusController::setContainingWindowIsVisible(bool containingWindowIsVisibl } } +#if ENABLE(TIZEN_FOCUS_UI) +static IntSize frameOffset(Frame* initialFrame) +{ + IntSize offset; + for (Frame* frame = initialFrame; frame; frame = frame->tree()->parent()) { + RenderBoxModelObject* renderer; + if (frame->ownerElement() && (renderer = frame->ownerElement()->renderBoxModelObject())) { + do { + offset.expand(renderer->offsetLeft(), renderer->offsetTop()); + } while ((renderer = renderer->offsetParent())); + offset -= frame->view()->scrollOffset(); + } + } + return offset; +} + +static bool isTopmostNode(const FocusCandidate& candidate) +{ + Node* candidateNode = candidate.visibleNode; + if (candidateNode->isFrameOwnerElement()) + return true; + + Frame* frame = candidateNode->document()->frame(); + EventHandler* eventHandler = frame->eventHandler(); + IntSize offset(frameOffset(frame)); + + Node* childNode; + if (candidateNode->hasTagName(HTMLNames::aTag)) + childNode = candidateNode->firstChild(); + else + childNode = 0; + + Region region(pixelSnappedIntRect(candidate.rect)); + + while (!region.isEmpty()) { + Vector rects = region.rects(); + HitTestResult result = eventHandler->hitTestResultAtPoint(IntPoint(rects[0].x(), rects[0].y()) - offset, false); + + Node* node = result.innerNode(); + if (!node || !node->parentNode() || node->parentNode()->isDocumentNode() || candidateNode->contains(node)) + return true; + + if (node->hasTagName(HTMLNames::areaTag)) + node = static_cast(node)->imageElement(); + + ASSERT(node && node->renderer() && node->renderer()->enclosingLayer()); + IntRect layerRect(node->renderer()->enclosingLayer()->absoluteBoundingBox()); + layerRect.move(frameOffset(node->document()->frame())); + if (!layerRect.intersects(rects[0])) + return true; + + region.subtract(layerRect); + + while (childNode && region.isEmpty()) { + if (childNode->renderer()) + region.intersect(pixelSnappedIntRect(nodeRectInAbsoluteCoordinates(childNode))); + childNode = childNode->nextSibling(); + } + } + + return false; +} + +static bool isSuitableCandidate(FocusDirection direction, const FocusCandidate& candidate, const FocusCandidate& closest) +{ + ASSERT(candidate.alignment != closest.alignment); + if (candidate.alignment == None) + return false; + if (closest.alignment == None) + return true; + + long long candidateDistance = candidate.distance; + long long closestDistance = closest.distance; + + if (candidate.alignment < closest.alignment) { + if (direction == FocusDirectionLeft || direction == FocusDirectionRight) + candidateDistance += candidate.rect.width().toInt(); + else + candidateDistance += candidate.rect.height().toInt(); + } else { + if (direction == FocusDirectionLeft || direction == FocusDirectionRight) + closestDistance += closest.rect.width().toInt(); + else + closestDistance += closest.rect.height().toInt(); + } + + return candidateDistance < closestDistance; +} +#endif + static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCandidate& current, FocusCandidate& candidate, FocusCandidate& closest) { ASSERT(candidate.visibleNode->isElementNode()); @@ -751,6 +849,11 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCa if (candidate.isOffscreenAfterScrolling && candidate.alignment < Full) return; +#if ENABLE(TIZEN_FOCUS_UI) + if (!isTopmostNode(candidate)) + return; +#endif + if (closest.isNull()) { closest = candidate; return; @@ -776,8 +879,13 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCa return; } +#if ENABLE(TIZEN_FOCUS_UI) + if (isSuitableCandidate(direction, candidate, closest)) + closest = candidate; +#else if (candidate.alignment > closest.alignment) closest = candidate; +#endif } void FocusController::findFocusCandidateInContainer(Node* container, const LayoutRect& startingRect, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closest) @@ -798,7 +906,11 @@ void FocusController::findFocusCandidateInContainer(Node* container, const Layou if (!node->isElementNode()) continue; +#if ENABLE(TIZEN_FOCUS_UI) + if ((!node->isFocusable() && !node->isFrameOwnerElement() && !canScrollInDirection(node, direction)) || m_excludedCandidateSet.contains(node)) +#else if (!node->isKeyboardFocusable(event) && !node->isFrameOwnerElement() && !canScrollInDirection(node, direction)) +#endif continue; FocusCandidate candidate = FocusCandidate(node, direction); @@ -849,7 +961,12 @@ bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons frameElement->contentFrame()->document()->updateLayoutIgnorePendingStylesheets(); if (!advanceFocusDirectionallyInContainer(frameElement->contentFrame()->document(), rect, direction, event)) { // The new frame had nothing interesting, need to find another candidate. +#if ENABLE(TIZEN_FOCUS_UI) + m_excludedCandidateSet.add(focusCandidate.visibleNode); + return advanceFocusDirectionallyInContainer(container, newStartingRect, direction, event); +#else return advanceFocusDirectionallyInContainer(container, nodeRectInAbsoluteCoordinates(focusCandidate.visibleNode, true), direction, event); +#endif } return true; } @@ -872,6 +989,13 @@ bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons return true; } +#if ENABLE(TIZEN_FOCUS_UI) + if (focusCandidate.isOffscreen) { + Node* container = focusCandidate.enclosingScrollableBox; + scrollInDirection(container, direction); + } +#endif + // We found a new focus node, navigate to it. Element* element = toElement(focusCandidate.focusableNode); ASSERT(element); @@ -917,6 +1041,9 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa static_cast(container)->updateLayoutIgnorePendingStylesheets(); } while (!consumed && container); +#if ENABLE(TIZEN_FOCUS_UI) + m_excludedCandidateSet.clear(); +#endif return consumed; } diff --git a/Source/WebCore/page/SpatialNavigation.cpp b/Source/WebCore/page/SpatialNavigation.cpp old mode 100644 new mode 100755 index 4150b64..614d169 --- a/Source/WebCore/page/SpatialNavigation.cpp +++ b/Source/WebCore/page/SpatialNavigation.cpp @@ -84,6 +84,12 @@ FocusCandidate::FocusCandidate(Node* node, FocusDirection direction) visibleNode = node; rect = nodeRectInAbsoluteCoordinates(node, true /* ignore border */); } +#if ENABLE(TIZEN_FOCUS_UI) + if (rect.isEmpty() || rect.maxX() < 0 || rect.maxY() < 0) { + visibleNode = 0; + return; + } +#endif focusableNode = node; isOffscreen = hasOffscreenRect(visibleNode); @@ -170,8 +176,10 @@ static bool areRectsFullyAligned(FocusDirection direction, const LayoutRect& a, aStart = start(direction, a); bStart = start(direction, b); +#if !ENABLE(TIZEN_FOCUS_UI) LayoutUnit aMiddle = middle(direction, a); LayoutUnit bMiddle = middle(direction, b); +#endif aEnd = end(direction, a); bEnd = end(direction, b); @@ -200,10 +208,14 @@ static bool areRectsFullyAligned(FocusDirection direction, const LayoutRect& a, // * * * * * * // **************************** ***************************** +#if ENABLE(TIZEN_FOCUS_UI) + return (aStart <= bStart && aEnd >= bEnd) || (bStart <= aStart && bEnd >= aEnd); +#else return ((bMiddle >= aStart && bMiddle <= aEnd) // (1) || (aMiddle >= bStart && aMiddle <= bEnd) // (2) || (bStart == aStart) // (3) || (bEnd == aEnd)); // (4) +#endif } // This method checks if |start| and |dest| have a partial intersection, either @@ -506,12 +518,22 @@ static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRec { LayoutRect rect = initialRect; for (Frame* frame = initialFrame; frame; frame = frame->tree()->parent()) { +#if ENABLE(TIZEN_FOCUS_UI) + RenderBoxModelObject* renderer; + if (frame->ownerElement() && (renderer = frame->ownerElement()->renderBoxModelObject())) { + do { + rect.move(renderer->offsetLeft(), renderer->offsetTop()); + } while ((renderer = renderer->offsetParent())); + rect.move(-frame->view()->scrollOffset()); + } +#else if (Element* element = static_cast(frame->ownerElement())) { do { rect.move(element->offsetLeft(), element->offsetTop()); } while ((element = element->offsetParent())); rect.move((-frame->view()->scrollOffset())); } +#endif } return rect; } @@ -522,7 +544,13 @@ LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) if (node->isDocumentNode()) return frameRectInAbsoluteCoordinates(static_cast(node)->frame()); +#if ENABLE(TIZEN_FOCUS_UI) + LayoutRect rect = node->getRect(); + rect.intersect(node->renderer()->absoluteClippedOverflowRect()); + rect = rectToAbsoluteCoordinates(node->document()->frame(), rect); +#else LayoutRect rect = rectToAbsoluteCoordinates(node->document()->frame(), node->getRect()); +#endif // For authors that use border instead of outline in their CSS, we compensate by ignoring the border when calculating // the rect of the focused element. diff --git a/Source/WebKit2/PlatformTizen.cmake b/Source/WebKit2/PlatformTizen.cmake index b876450..433b9c6 100755 --- a/Source/WebKit2/PlatformTizen.cmake +++ b/Source/WebKit2/PlatformTizen.cmake @@ -295,3 +295,9 @@ IF (ENABLE_TIZEN_SCREEN_READER) ADD_DEFINITIONS(-DSCREEN_READER_FOCUS_RING_IMAGE_PATH="${SCREEN_READER_FOCUS_RING_IMAGE_PATH}/screenReaderFocusRing.png") INSTALL(FILES ${WEBKIT2_DIR}/UIProcess/API/efl/tizen/images/screenReaderFocusRing.png DESTINATION ${SCREEN_READER_FOCUS_RING_IMAGE_PATH}) ENDIF () + +IF (ENABLE_TIZEN_FOCUS_UI) + SET(FOCUS_UI_FOCUS_RING_IMAGE_PATH ${CMAKE_INSTALL_PREFIX}/share/${WebKit2_LIBRARY_NAME}-${PROJECT_VERSION_MAJOR}/images) + ADD_DEFINITIONS(-DFOCUS_UI_FOCUS_RING_IMAGE_PATH="${FOCUS_UI_FOCUS_RING_IMAGE_PATH}/focusUIFocusRing.png") + INSTALL(FILES ${WEBKIT2_DIR}/UIProcess/API/efl/tizen/images/focusUIFocusRing.png DESTINATION ${FOCUS_UI_FOCUS_RING_IMAGE_PATH}) +ENDIF () diff --git a/Source/WebKit2/UIProcess/API/efl/EwkViewImpl.cpp b/Source/WebKit2/UIProcess/API/efl/EwkViewImpl.cpp index 371af74..24da214 100755 --- a/Source/WebKit2/UIProcess/API/efl/EwkViewImpl.cpp +++ b/Source/WebKit2/UIProcess/API/efl/EwkViewImpl.cpp @@ -1259,6 +1259,11 @@ void EwkViewImpl::feedTouchEvents(Ewk_Touch_Event_Type type) if (!count) return; +#if ENABLE(TIZEN_FOCUS_UI) + if (type == EWK_TOUCH_START) + pageProxy->setSpatialNavigationEnabled(false); +#endif + Eina_List* points = 0; for (unsigned i = 0; i < count; ++i) { Ewk_Touch_Point* point = new Ewk_Touch_Point; @@ -1415,4 +1420,16 @@ void EwkViewImpl::didChangeScrollAndScale(const WebCore::IntPoint& previousScrol focusRing->updateScrollAndScale(previousScrollPosition, previousScale); #endif } + +#if ENABLE(TIZEN_FOCUS_UI) +void EwkViewImpl::pages(Vector >& pages) +{ + pages.resize(pageViewMap.size()); + + PageViewMap::const_iterator::Keys it = pageViewMap.begin().keys(); + PageViewMap::const_iterator::Keys end = pageViewMap.end().keys(); + for (unsigned i = 0; it != end; ++it, ++i) + pages[i] = toImpl(*it); +} +#endif #endif //#if OS(TIZEN) diff --git a/Source/WebKit2/UIProcess/API/efl/EwkViewImpl.h b/Source/WebKit2/UIProcess/API/efl/EwkViewImpl.h index 2b1e9bf..dfe660f 100755 --- a/Source/WebKit2/UIProcess/API/efl/EwkViewImpl.h +++ b/Source/WebKit2/UIProcess/API/efl/EwkViewImpl.h @@ -324,6 +324,10 @@ public: #endif void didChangeScrollAndScale(const WebCore::IntPoint&, float); + +#if ENABLE(TIZEN_FOCUS_UI) + static void pages(Vector >&); +#endif #endif // #if OS(TIZEN) // FIXME: Make members private for encapsulation. diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp index 82f34e6..2ca3aee 100755 --- a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp @@ -2501,17 +2501,6 @@ bool ewk_view_focused_node_adjust(Evas_Object* ewkView, Eina_Bool adjustForExter #endif #if ENABLE(TIZEN_ISF_PORT) - Ecore_X_Window rootWin = ecore_x_window_root_first_get(); - ecore_x_event_mask_set(rootWin, ECORE_X_EVENT_MASK_WINDOW_PROPERTY); - Ecore_X_Atom xAtom = ecore_x_atom_get("X External Keyboard Exist"); - unsigned int connectedKeyboardNum = 0; - bool isExternalKeyboardConnected = false; - - // get connected keyboard number - if (ecore_x_window_prop_card32_get(rootWin, xAtom, &connectedKeyboardNum, 1) - && connectedKeyboardNum) - isExternalKeyboardConnected = true; - // We should treat both of ECORE_IMF_INPUT_PANEL_STATE_SHOW and ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW // as IME is shown. ECORE_IMF_INPUT_PANEL_STATE_HIDE is ignored at here. // input field zoom should not work with below conditions @@ -2520,7 +2509,7 @@ bool ewk_view_focused_node_adjust(Evas_Object* ewkView, Eina_Bool adjustForExter // 3. imfContext is null(if adjustForExternalKeyboard is false) // 4. input panel state is hidden(if adjustForExternalKeyboard is false) if ((!(static_cast(impl->pageClient.get()))->isViewFocused() - || (adjustForExternalKeyboard && !isExternalKeyboardConnected) + || (adjustForExternalKeyboard && !InputMethodContextEfl::shouldUseExternalKeyboard()) || (!adjustForExternalKeyboard && !impl->inputMethodContext()) || (!adjustForExternalKeyboard && !impl->inputMethodContext()->isShow())) #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD) diff --git a/Source/WebKit2/UIProcess/API/efl/tizen/images/focusUIFocusRing.png b/Source/WebKit2/UIProcess/API/efl/tizen/images/focusUIFocusRing.png new file mode 100755 index 0000000..4029269 Binary files /dev/null and b/Source/WebKit2/UIProcess/API/efl/tizen/images/focusUIFocusRing.png differ diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp index cbc652a..1b39b9c 100755 --- a/Source/WebKit2/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp @@ -260,6 +260,9 @@ WebPageProxy::WebPageProxy(PageClient* pageClient, PassRefPtr p #if ENABLE(TIZEN_WEBKIT2_NOTIFY_SUSPEND_BY_REMOTE_WEB_INSPECTOR) , m_contentSuspendedByInspector(false) #endif +#if ENABLE(TIZEN_FOCUS_UI) + , m_spatialNavigationEnabled(false) +#endif { #ifndef NDEBUG webPageProxyCounter.increment(); diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index 28e8fed..0625414 100755 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -1030,10 +1030,13 @@ public: void recalcScreenReaderFocusRect(); void clearScreenReader(); - void didScreenReaderFocusRectChanged(const WebCore::IntRect&); void didScreenReaderTextChanged(const String&); #endif +#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) + void didChangeFocusedRect(const WebCore::IntRect&); +#endif + #if ENABLE(TIZEN_CSP) void setContentSecurityPolicy(const String& policy, WebCore::ContentSecurityPolicy::HeaderType type); #endif @@ -1058,6 +1061,10 @@ public: void useSettingsFont(); #endif +#if ENABLE(TIZEN_FOCUS_UI) + void setSpatialNavigationEnabled(bool); +#endif + private: WebPageProxy(PageClient*, PassRefPtr, WebPageGroup*, uint64_t pageID); @@ -1703,6 +1710,10 @@ private: #if ENABLE(TIZEN_FILE_SYSTEM) RefPtr m_exceededLocalFileSystemQuotaReply; #endif + +#if ENABLE(TIZEN_FOCUS_UI) + bool m_spatialNavigationEnabled; +#endif }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebPageProxy.messages.in b/Source/WebKit2/UIProcess/WebPageProxy.messages.in index 3eb8354..7665ffc 100755 --- a/Source/WebKit2/UIProcess/WebPageProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebPageProxy.messages.in @@ -458,10 +458,13 @@ messages -> WebPageProxy { #endif #if ENABLE(TIZEN_SCREEN_READER) - DidScreenReaderFocusRectChanged(WebCore::IntRect rect) DidScreenReaderTextChanged(WTF::String text) #endif +#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) + DidChangeFocusedRect(WebCore::IntRect rect) +#endif + #if ENABLE(TIZEN_INDEXED_DATABASE) ExceededIndexedDatabaseQuota(uint64_t frameID, WTF::String originIdentifier, int64_t currentUsage) -> (bool returnValue) Delayed #endif diff --git a/Source/WebKit2/UIProcess/efl/InputMethodContextEfl.cpp b/Source/WebKit2/UIProcess/efl/InputMethodContextEfl.cpp index 15b8b5a..8506a91 100755 --- a/Source/WebKit2/UIProcess/efl/InputMethodContextEfl.cpp +++ b/Source/WebKit2/UIProcess/efl/InputMethodContextEfl.cpp @@ -32,6 +32,52 @@ namespace WebKit { #if ENABLE(TIZEN_ISF_PORT) const unsigned InputMethodContextEfl::maxContextSize = 10; +Ecore_X_Atom InputMethodContextEfl::s_externalKeyboardProperty = 0; +bool InputMethodContextEfl::s_shouldUseExternalKeyboard = false; + +void InputMethodContextEfl::initializeExternalKeyboard() +{ + s_externalKeyboardProperty = ecore_x_atom_get("X External Keyboard Exist"); + if (!s_externalKeyboardProperty) + return; + + Ecore_X_Window rootWin = ecore_x_window_root_first_get(); + ecore_x_event_mask_set(rootWin, ECORE_X_EVENT_MASK_WINDOW_PROPERTY); + + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, windowPropertyChanged, 0); + + unsigned int value; + if (ecore_x_window_prop_card32_get(rootWin, s_externalKeyboardProperty, &value, 1) <= 0) + return; + + s_shouldUseExternalKeyboard = value; +} + +Eina_Bool InputMethodContextEfl::windowPropertyChanged(void*, int, void* event) +{ + Ecore_X_Event_Window_Property* propertyEvent = static_cast(event); + + if (propertyEvent->atom != s_externalKeyboardProperty) + return ECORE_CALLBACK_PASS_ON; + + unsigned int value; + if (ecore_x_window_prop_card32_get(propertyEvent->win, s_externalKeyboardProperty, &value, 1) <= 0 || s_shouldUseExternalKeyboard == value) + return ECORE_CALLBACK_PASS_ON; + + s_shouldUseExternalKeyboard = value; + +#if ENABLE(TIZEN_FOCUS_UI) + if (!s_shouldUseExternalKeyboard) { + Vector > pages; + EwkViewImpl::pages(pages); + + for (size_t i = 0; i < pages.size(); ++i) + pages[i]->setSpatialNavigationEnabled(false); + } +#endif + + return ECORE_CALLBACK_PASS_ON; +} #endif InputMethodContextEfl::InputMethodContextEfl(EwkViewImpl* viewImpl, PassOwnPtr context) @@ -46,7 +92,10 @@ InputMethodContextEfl::InputMethodContextEfl(EwkViewImpl* viewImpl, PassOwnPtrpage()->setSpatialNavigationEnabled(true); +#endif + #if ENABLE(TIZEN_ISF_PORT) if (!m_context) return; diff --git a/Source/WebKit2/UIProcess/efl/InputMethodContextEfl.h b/Source/WebKit2/UIProcess/efl/InputMethodContextEfl.h index 114707c..f26f4d9 100755 --- a/Source/WebKit2/UIProcess/efl/InputMethodContextEfl.h +++ b/Source/WebKit2/UIProcess/efl/InputMethodContextEfl.h @@ -26,6 +26,10 @@ #include #include +#if ENABLE(TIZEN_ISF_PORT) +#include +#endif + class EwkViewImpl; namespace WebKit { @@ -53,6 +57,8 @@ public: void updateTextInputState(); #if ENABLE(TIZEN_ISF_PORT) + static bool shouldUseExternalKeyboard() { return s_shouldUseExternalKeyboard; } + bool isShow(); Ecore_IMF_Autocapital_Type autoCapitalType(); void onFocusIn(); @@ -73,7 +79,8 @@ private: static void onIMFPreeditSequenceChanged(void* data, Ecore_IMF_Context*, void* eventInfo); #if ENABLE(TIZEN_ISF_PORT) - void initializeIMFContext(Ecore_IMF_Context*, Ecore_IMF_Input_Panel_Layout, int, Ecore_IMF_Input_Panel_Return_Key_Type); + static void initializeExternalKeyboard(); + static Eina_Bool windowPropertyChanged(void*, int, void*); static void onIMFInputPanelStateChanged(void*, Ecore_IMF_Context*, int); static void onIMFInputPanelGeometryChanged(void*, Ecore_IMF_Context*, int); @@ -82,6 +89,8 @@ private: static Eina_Bool onIMFRetrieveSurrounding(void*, Ecore_IMF_Context*, char**, int*); static void onIMFDeleteSurrounding(void*, Ecore_IMF_Context*, void*); + void initializeIMFContext(Ecore_IMF_Context*, Ecore_IMF_Input_Panel_Layout, int, Ecore_IMF_Input_Panel_Return_Key_Type); + PassOwnPtr takeContext(uintptr_t); void setIMFContext(const EditorState&); void revertIMFContext(); @@ -107,6 +116,9 @@ private: #if ENABLE(TIZEN_ISF_PORT) static const unsigned maxContextSize; + static Ecore_X_Atom s_externalKeyboardProperty; + static bool s_shouldUseExternalKeyboard; + Vector > > m_contextList; uintptr_t m_contextID; int m_state; diff --git a/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp b/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp index 720a9a8..3d7b14d 100755 --- a/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp +++ b/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp @@ -1037,7 +1037,14 @@ void WebPageProxy::clearScreenReader() process()->send(Messages::WebPage::ClearScreenReader(), m_pageID); } -void WebPageProxy::didScreenReaderFocusRectChanged(const IntRect& rect) +void WebPageProxy::didScreenReaderTextChanged(const String& text) +{ + ScreenReaderProxy::screenReader().setText(text); +} +#endif + +#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) +void WebPageProxy::didChangeFocusedRect(const IntRect& rect) { #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING) FocusRing* focusRing = ewkViewGetFocusRing(viewWidget()); @@ -1051,11 +1058,7 @@ void WebPageProxy::didScreenReaderFocusRectChanged(const IntRect& rect) #else UNUSED_PARAM(rect); #endif -} -void WebPageProxy::didScreenReaderTextChanged(const String& text) -{ - ScreenReaderProxy::screenReader().setText(text); } #endif @@ -1241,4 +1244,20 @@ void WebPageProxy::setContentSuspendedByInspector(bool isSuspended) } #endif +#if ENABLE(TIZEN_FOCUS_UI) +void WebPageProxy::setSpatialNavigationEnabled(bool enabled) +{ + if (m_spatialNavigationEnabled == enabled) + return; + + m_spatialNavigationEnabled = enabled; + + if (enabled) + static_cast(m_pageClient)->viewImpl()->focusRing->setImage(FOCUS_UI_FOCUS_RING_IMAGE_PATH, 4, 2); + else + static_cast(m_pageClient)->viewImpl()->focusRing->setImage(String(), 0, 0); + + process()->send(Messages::WebPage::SetSpatialNavigationEnabled(enabled), m_pageID); +} +#endif } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp index 166b8b5..734b39d 100755 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp @@ -172,6 +172,11 @@ void WebChromeClient::focusedNodeChanged(Node* node) nodeRect.setY(nodeRect.y() / m_page->pageScaleFactor()); } m_page->send(Messages::WebPageProxy::FocusedNodeChanged(nodeRect)); + +#if ENABLE(TIZEN_FOCUS_UI) + if (m_page->corePage()->settings()->isSpatialNavigationEnabled()) + m_page->didChangeFocusedRect(m_page->corePage()->focusController()->focusedOrMainFrame()->document()->focusedNode()); +#endif #else notImplemented(); #endif @@ -486,6 +491,10 @@ void WebChromeClient::scroll(const IntSize& scrollOffset, const IntRect& scrollR void WebChromeClient::delegatedScrollRequested(const IntPoint& scrollOffset) { m_page->pageDidRequestScroll(scrollOffset); + +#if OS(TIZEN) + m_page->didChangeContents(m_page->bounds()); +#endif } #endif diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h index 6257029..d90c3df 100755 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.h +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h @@ -815,6 +815,10 @@ public: WebCore::IntRect nodeRect(WebCore::Node*) const; #endif +#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) + void didChangeFocusedRect(WebCore::Node*); +#endif + #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL) void notifyTransitionToCommitted(bool); #endif @@ -839,6 +843,10 @@ public: void didChangeContents(const WebCore::IntRect&); #endif +#if ENABLE(TIZEN_FOCUS_UI) + void setSpatialNavigationEnabled(bool); +#endif + private: WebPage(uint64_t pageID, const WebPageCreationParameters&); @@ -1193,6 +1201,10 @@ private: OwnPtr m_screenReader; #endif +#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) + WebCore::IntRect m_focusedRect; +#endif + #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION) EditorState m_editorState; #endif diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in index 4e204a2..11b2b47 100755 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in @@ -459,4 +459,8 @@ messages -> WebPage { #if ENABLE(TIZEN_USE_SETTINGS_FONT) UseSettingsFont() #endif + +#if ENABLE(TIZEN_FOCUS_UI) + SetSpatialNavigationEnabled(bool enabled) +#endif } diff --git a/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp index 1111865..785697b 100755 --- a/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp +++ b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp @@ -1723,31 +1723,13 @@ void WebPage::getLinkMagnifierRect(const IntPoint& position, const IntSize& size #endif #if ENABLE(TIZEN_SCREEN_READER) -static void sendScreenReaderFocusRect(WebPage* page, ScreenReader* screenReader) -{ - Node* node = screenReader->getFocusedNode(); - IntRect rect; - - if (node) { - bool isImage = false; - if (node->isElementNode()) { - Element* element = static_cast(node); - isImage = !element->getAttribute(element->imageSourceAttributeName()).isEmpty(); - } - rect = getNodeRect(node, node, isImage); - } - - screenReader->setFocusedRect(rect); - page->send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(rect)); -} - void WebPage::moveScreenReaderFocus(bool forward, bool& result) { if (!m_screenReader) m_screenReader = ScreenReader::create(this); result = m_screenReader->moveFocus(forward); - sendScreenReaderFocusRect(this, m_screenReader.get()); + didChangeFocusedRect(m_screenReader->getFocusedNode()); } void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point) @@ -1758,7 +1740,7 @@ void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point) if (!m_screenReader->moveFocus(point)) return; - sendScreenReaderFocusRect(this, m_screenReader.get()); + didChangeFocusedRect(m_screenReader->getFocusedNode()); } void WebPage::clearScreenReaderFocus() @@ -1814,7 +1796,7 @@ void WebPage::recalcScreenReaderFocusRect() if (!m_screenReader || !m_screenReader->getFocusedNode()) return; - sendScreenReaderFocusRect(this, m_screenReader.get()); + didChangeFocusedRect(m_screenReader->getFocusedNode()); } void WebPage::updateScreenReaderFocus(RenderObject* object) @@ -1827,7 +1809,8 @@ void WebPage::updateScreenReaderFocus(RenderObject* object) else if (!m_screenReader->rendererWillBeDestroyed(object)) return; - sendScreenReaderFocusRect(this, m_screenReader.get()); + m_focusedRect = IntRect(); + didChangeFocusedRect(m_screenReader->getFocusedNode()); } void WebPage::clearScreenReader() @@ -1883,6 +1866,14 @@ IntRect WebPage::nodeRect(Node* node) const } #endif +#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) +void WebPage::didChangeFocusedRect(WebCore::Node* node) +{ + m_focusedRect = nodeRect(node); + send(Messages::WebPageProxy::DidChangeFocusedRect(m_focusedRect)); +} +#endif + #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL) // FIXME: Currently with cached pages, hiding Popup list menu is not working correctly. // This patch is a fix allowing any popup list menu to get close for any page navigation. @@ -1962,11 +1953,22 @@ void WebPage::didChangeContents(const IntRect& rect) } #endif -#if ENABLE(TIZEN_SCREEN_READER) - if (m_screenReader && rect.intersects(m_screenReader->focusedRect())) - recalcScreenReaderFocusRect(); +#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) + if (rect.intersects(m_focusedRect)) { + if (m_screenReader) + didChangeFocusedRect(m_screenReader->getFocusedNode()); + else if (m_page->settings()->isSpatialNavigationEnabled()) + didChangeFocusedRect(frame->document()->focusedNode()); + } #endif } + +#if ENABLE(TIZEN_FOCUS_UI) +void WebPage::setSpatialNavigationEnabled(bool enabled) +{ + m_page->settings()->setSpatialNavigationEnabled(enabled); +} +#endif #endif // #if OS(TIZEN) } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/efl/tizen/ScreenReader.cpp b/Source/WebKit2/WebProcess/WebPage/efl/tizen/ScreenReader.cpp index d168974..ac1ba95 100755 --- a/Source/WebKit2/WebProcess/WebPage/efl/tizen/ScreenReader.cpp +++ b/Source/WebKit2/WebProcess/WebPage/efl/tizen/ScreenReader.cpp @@ -579,7 +579,6 @@ bool ScreenReader::rendererWillBeDestroyed(RenderObject* object) void ScreenReader::clearFocus() { m_focusedObject = 0; - m_focusedRect = IntRect(); m_hasFocus = false; m_page->send(Messages::WebPageProxy::DidScreenReaderTextChanged(emptyString())); } diff --git a/Source/WebKit2/WebProcess/WebPage/efl/tizen/ScreenReader.h b/Source/WebKit2/WebProcess/WebPage/efl/tizen/ScreenReader.h index c6d45ed..41bf628 100755 --- a/Source/WebKit2/WebProcess/WebPage/efl/tizen/ScreenReader.h +++ b/Source/WebKit2/WebProcess/WebPage/efl/tizen/ScreenReader.h @@ -57,9 +57,6 @@ public: bool rendererWillBeDestroyed(WebCore::RenderObject*); void clearFocus(); - const WebCore::IntRect& focusedRect() const { return m_focusedRect; } - void setFocusedRect(const WebCore::IntRect& rect) { m_focusedRect = rect; } - private: ScreenReader(WebPage*); @@ -73,7 +70,6 @@ private: WebPage* m_page; WebCore::RenderObject* m_focusedObject; - WebCore::IntRect m_focusedRect; bool m_hasFocus; bool m_isForward; diff --git a/Source/cmake/OptionsTizen.cmake b/Source/cmake/OptionsTizen.cmake old mode 100644 new mode 100755 index 1275fc5..8719beb --- a/Source/cmake/OptionsTizen.cmake +++ b/Source/cmake/OptionsTizen.cmake @@ -383,6 +383,9 @@ IF (ENABLE_TIZEN_SCREEN_READER) ADD_DEFINITIONS(-DHAVE_ACCESSIBILITY=1) ENDIF() +SET(ENABLE_TIZEN_FOCUS_UI 1) +ADD_DEFINITIONS(-DENABLE_TIZEN_FOCUS_UI=1) + INCLUDE_IF_EXISTS(${CMAKE_CURRENT_SOURCE_DIR}/Source/cmake/OptionsExperimental.cmake) MESSAGE("Finish to check Tizen dependencies")