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方法:
这就是浏览器内部默认处理按键的地方,该方法里面调用了defaultArrowEventHandler方法,这个方法就是处理锚点移动的,在实际调试中,发现在调用handleKeyboardEvent方法的时候,事件居然被处理了WebEditorClientGtk.cpp下的handleKeyboardEvent方法当成字符串处理了,处理办法也很简单,见下红色部分:
终于可以进defaultArrowEventHandler函数了
可是在isSpatialNavigationEnabled返回了,不过这个就简单了,这个配置是通过Settings类设置的,你只要找到这个类,调用它的setSpatialNavigationEnabled(bool Enable)方法就可以了
经过一系列修改,哈哈,方向键就可以移动焦点了
本文章只使用与在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)方法就可以了
经过一系列修改,哈哈,方向键就可以移动焦点了
相关文章推荐
- Linux socket 初步
- Android学习笔记(二九):嵌入浏览器
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程