您的位置:首页 > 运维架构 > Linux

webkit linux 方向键移动焦点

2016-03-17 16:23 375 查看
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类设置的,你只要找到这个类,调用它的setSpatialNavigationEnabled(bool Enable)方法就可以了

经过一系列修改,哈哈,方向键就可以移动焦点了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息