给webkit增加一个系统事件

   在开发一个项目的时候,有个需求,需要让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!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值