给webkit增加一个系统事件
来源:互联网 发布:淘宝已评论怎么看不到 编辑:程序博客网 时间:2024/05/21 15:03
在开发一个项目的时候,有个需求,需要让JS能够接收C的事件。如何实现呢!?其实DOM中已经有一个类似的实现,就是document.keypress。页面通过注册keypress事件的回调获取按键信息,而按键信息就是由底层送上来的。
依葫芦画瓢,再添加多一个document.onsystemevent到webkit中。
首先需要在document对象的C++实现中增加onsystemevent成员,如下:
在Source/WebCore/dom/Document.cpp中加入:
/*
add by junhai.xiao 20140115
为document 增加两个成员onsystemnotify onsystemevent
以下是这两个成员对应的C函数,
其实调用了onsystemnotify来注册listener
*/
EventListener* Document::onsystemevent()
{
return getAttributeEventListener(eventNames().systemnotifyEvent);
}
void Document::setOnsystemevent(PassRefPtr<EventListener> listener)
{
setAttributeEventListener(eventNames().systemnotifyEvent, listener);
}
/*add end*/
相应的头文件也加入声明。
注意在Document.idl中加入对onsystemnotify属性的声明。
/*add by junhai.xiao 20140115
为document 增加两个成员onsystemnotify onsystemevent
两个成员其实是一样的,onsystemevent最终调用onsystemnotify
*/
attribute [NotEnumerable] EventListener onsystemnotify;
attribute [NotEnumerable] EventListener onsystemevent;//onsystemevent 和onsystemnotify一样
/*add end*/
到此为止,已经为document添加了onsystemevent属性。
下一步需要在event对象中加入新的事件类型:SYSTEMNOTIFY,以及系统事件需要存储的事件变量: , m_systemnotify_value,m_modifiers
在Event.h中的EventType枚举中加入:
SYSTEMNOTIFY = 65536,/*add by junhai.xiao 增加一个系统信息类型*
在方法声明中加入:
/*add by junhai.xiao 增加以便上层获知是否有JS处理该事件*/
unsigned int modifiers() const { return m_modifiers; }/*在js中可以调用*/
void set_modifiers(unsigned int modifiers) { m_modifiers = modifiers; }
void set_systemnotify_value(unsigned int systemnotify_val){ m_systemnotify_value = systemnotify_val;}
const unsigned int get_systemnotify_value() const { return m_systemnotify_value;}
/*add end*/
event对应的idl中加入相应的信息。
现在event对象中也有我们需要的自定义属性了。
下一步是需要实现C++产生新的事件的代码了。
在PlatformKeyboardEventGtk.cpp加入:
bool PlatformKeyboardEvent::isGdkSystemEvent() const
{
//if(m_gdkEventKey->type == GDK_CLIENT_EVENT)
{
if(m_gdkEventKey->keyval == 0xfefeffff)
{
return true;
}
}
return false;
}
int PlatformKeyboardEvent::getGdkEventState () const
{
return (int)m_gdkEventKey->state;
}
在EventHandler.cpp中加入:
bool EventHandler::systemNotifyEvent(int type, int value, int modify)
{
if (!(m_frame->document()))
return false;
RefPtr<Node> node = eventTargetNodeForDocument(m_frame->document());
if (!node)
return false;
ExceptionCode ec;
const String keyIdentifier(" ");
RefPtr<KeyboardEvent> systemevent = \
KeyboardEvent::create(eventNames().systemnotifyEvent, true, false, \
m_frame->document()->defaultView(),\
keyIdentifier, 0, false, false, false,
false, false);
systemevent->set_modifiers(modify);
systemevent->set_systemnotify_value(value);/*相当于设置keycode*/
systemevent->setTarget(m_frame->document());
m_frame->document()->dispatchEvent(systemevent, ec);
return true;
}
keyEvent方法加入:
/*由于外部不能直接调用systemNotifyEvent,固由keyevent传递systemevent*/
if(initialKeyEvent.isGdkSystemEvent())
{
printf("[WEBKIT]System Event Get!\n");
bool ret;
WEBCORE_SYSTEM_EVENT_S *systemevent = (WEBCORE_SYSTEM_EVENT_S *)initialKeyEvent.getGdkEventState();
ret = systemNotifyEvent(systemevent->type,systemevent->value,systemevent->modify);
free(systemevent);
return ret;
}
到此webkit中的实现就完成了。
因为这个事GTK+WEBKIT的实现,当需要发生系统事件给js时,可以通过调用GTK的按键发送接口,配置按键类型为SYSTEMNOTIFY,利用state作为私有数据。
例如:
GdkEvent gdkevent;
memset(&gdkevent, 0, sizeof(GdkEvent));
WEBCORE_SYSTEM_EVENT_S *systemevent = (WEBCORE_SYSTEM_EVENT_S*)malloc(sizeof(WEBCORE_SYSTEM_EVENT_S));
memset(systemevent, 0x00, sizeof(WEBCORE_SYSTEM_EVENT_S));
systemevent->type = type;
systemevent->value = value;
systemevent->modify = modify;
gdkevent.key.type = GDK_KEY_PRESS;
gdkevent.key.keyval = WEBKIT_SYSTEMEVENT;
gdkevent.key.hardware_keycode = 4;
gdkevent.key.string = "";
gdkevent.key.length = 0;
gdkevent.key.state = systemevent;
gdkevent.key.window = gtk_widget_get_window(GTK_WIDGET(browser_window[0].web_view));
gdk_event_put(&gdkevent);
gtk_widget_queue_draw(browser_window[0].window);
如此,webkit收到gtk的按键,在eventhandle的keyevent方法中判断是systemevent就将这个event交给systemNotifyEvent方法 通过document的dispatchEvent方法送给js处理。
write by tsunami!
- 给webkit增加一个系统事件
- 给树莓派增加一个Linux系统调用
- 给对象增加一个简单的自定义事件机制
- 阅读笔记:如何给OpenSolaris增加一个系统调用
- 给控件增加响应事件
- 给UIImageView增加点击事件
- 给UIImageView增加点击事件
- 给LinearLayout增加点击事件
- 给Webkit内核的浏览器控件增加互交功能
- 给树莓派系统增加看门狗
- 给ironpython增加一个pythonw
- 给一个窗体增加快捷键
- 给查询增加一个序列
- 给分类增加一个属性
- 给eth0增加一个IP
- 给VML增加事件(九)
- 给dropdownlist增加onchange事件源代码
- 给FastReport4导出功能增加两个事件
- DWR 报错:Error: java.lang.SecurityException, Session Error 和 Allocate exception for servlet 问题的解决办法
- ie6中的透明图片的解决办法
- 常见算法:C语言求最小公倍数和最大公约数三种算法
- 5个日志数据:让你轻松分析系统性能
- 第九周项目三—输出星号图e
- 给webkit增加一个系统事件
- 导入android工程后没有自动关联android.jar包的原因
- java之URL(URL,URLConnection)实例
- assert断言使用
- 无需JavaScript!jQuery EasyUI构建CRUD应用程序的技巧
- hibernate之关于一对多单向关联映射
- WEB打印大全(转)
- 早读课广州站讲师——胡澈:产品经理在想什么?-20141028早读课
- javascript ajax请求封装和微信分享通用代码