webkit linux 方向键移动焦点

webkit linux 方向键移动焦点
本文章只使用与在linux平台下基于GTK的Webkit浏览器,其他平台可以参考。
总所周知,刚编译的浏览器或者PC上的浏览器,如果按方向键一般都是操作滚轮事件,想要获取某一元素焦点,要么就是鼠标移动上去,要么就是按TAB键一个一个移动。下面我将介绍如何修改代码实现上下左右键移动焦点;( 其实很简单
webkit事件处理不管port如何实现,最后其实都是调用EventHandler这个类来处理各种事件,对应EventHandler.cpp和EventHandler.h。一般一个事件从port层发给浏览器,都是先交给页面做处理,页面不处理则会交给浏览器默认处理。
这里有个关键方法keyEvent(),这个方法是处理事件的入口,一般不同的port层接收按键都会调用EventHandler类下的keyEvent方法传递按键,具体流程大家可以去Windows工程慢慢调试。
废话不多说,直接看EventHandler类的defaultKeyboardEventHandler方法:
void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
{
    if (event->type() == eventNames().keydownEvent) {
        m_frame.editor().handleKeyboardEvent(event);
        if (event->defaultHandled())
            return;
        if (event->keyIdentifier() == "U+0009")
            defaultTabEventHandler(event);
        else if (event->keyIdentifier() == "U+0008")
            defaultBackspaceEventHandler(event);
        else {
            FocusDirection direction = focusDirectionForKey(event->keyIdentifier());
            if (direction != FocusDirectionNone)
                <span style="color:#ff0000;">defaultArrowEventHandler</span>(direction, event);
        }
        handleKeyboardSelectionMovementForAccessibility(event);
    }
    if (event->type() == eventNames().keypressEvent) {
        m_frame.editor().handleKeyboardEvent(event);
        if (event->defaultHandled())
            return;
        if (event->charCode() == ' ')
            defaultSpaceEventHandler(event);
    }
}


这就是浏览器内部默认处理按键的地方,该方法里面调用了defaultArrowEventHandler方法,这个方法就是处理锚点移动的,在实际调试中,发现在调用 handleKeyboardEvent方法的时候,事件居然被处理了WebEditorClientGtk.cpp下的handleKeyboardEvent方法当成字符串处理了,处理办法也很简单,见下红色部分:
void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event)
{
    Node* node = event->target()->toNode();
    ASSERT(node);
    Frame* frame = node->document().frame();
    ASSERT(frame);

    const PlatformKeyboardEvent* platformEvent = event->keyEvent();
    if (!platformEvent)
        return;

    // If this was an IME event don't do anything.
    if (platformEvent->windowsVirtualKeyCode() == VK_PROCESSKEY ||
platformEvent->windowsVirtualKeyCode() ==VK_UP ||
platformEvent->windowsVirtualKeyCode() == VK_DOWN ||
platformEvent->windowsVirtualKeyCode() == VK_LEFT ||
platformEvent->windowsVirtualKeyCode() == VK_RIGHT)
        return;

    Vector<WTF::String> pendingEditorCommands;
    getEditorCommandsForKeyEvent(event, pendingEditorCommands);
    if (!pendingEditorCommands.isEmpty()) {

        // During RawKeyDown events if an editor command will insert text, defer
        // the insertion until the keypress event. We want keydown to bubble up
        // through the DOM first.
        if (platformEvent->type() == PlatformEvent::RawKeyDown) {
            if (executePendingEditorCommands(frame, pendingEditorCommands, false))
                event->setDefaultHandled();

            return;
        }

        // Only allow text insertion commands if the current node is editable.
        if (executePendingEditorCommands(frame, pendingEditorCommands, frame->editor().canEdit())) {
            event->setDefaultHandled();
            return;
        }
    }

    // Don't allow text insertion for nodes that cannot edit.
    if (!frame->editor().canEdit())
        return;

    // This is just a normal text insertion, so wait to execute the insertion
    // until a keypress event happens. This will ensure that the insertion will not
    // be reflected in the contents of the field until the keyup DOM event.
    if (event->type() != eventNames().keypressEvent)
        return;

    // Don't insert null or control characters as they can result in unexpected behaviour
    if (event->charCode() < ' ')
        return;

    // Don't insert anything if a modifier is pressed
    if (platformEvent->ctrlKey() || platformEvent->altKey())
        return;

    if (frame->editor().insertText(platformEvent->text(), event))
        event->setDefaultHandled();
}



终于可以进defaultArrowEventHandler函数了
void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, KeyboardEvent* event)
{
    ASSERT(event->type() == eventNames().keydownEvent);

    if (event->ctrlKey() || event->metaKey() || event->altGraphKey() || event->shiftKey())
        return;

    Page* page = m_frame.page();
    if (!page)
        return;

    if (!<span style="color:#ff0000;">isSpatialNavigationEnabled</span>(&m_frame))  
        return;

    // Arrows and other possible directional navigation keys can be used in design
    // mode editing.
    if (m_frame.document()->inDesignMode())
        return;

    if (page->focusController().advanceFocus(focusDirection, event))
        event->setDefaultHandled();
}


可是在 isSpatialNavigationEnabled返回了,不过这个就简单了,这个配置是通过Settings类设置的,你只要找到这个类,调用它的 set SpatialNavigationEnabled(bool Enable)方法就可以了

经过一系列修改,哈哈,方向键就可以移动焦点了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值