Webkit Painting and Event Flow 绘屏和事件 探讨
来源:互联网 发布:万能票据打印软件 编辑:程序博客网 时间:2024/05/24 00:20
http://blog.csdn.net/robinqcn/article/details/3777477
WebKit来自khtml, 以前khtml中, 整个页面是一个大qscrollview, 网页上的控制元素就是Qt里的控件, 可能是为了移植方面原因, 现在webkit中没有用传统的控件概念来实现网页上的button等元素, 而是把控件的两个主要功能分离出来, (painting 和 事件响应 ) 各走一套接口和platform对接. Webkit自己来完成整个 事件-响应-绘图 的逻辑. 对于移植来说, 这自然是一个很好的构架, 不用深入内部, 只要把两头接口做好就OK了: 丢进去事件, 等待WebKit来调用paint函数.
事件
为了理清楚事件的流程, 我用gdb来帮忙. 在浩如烟海的的代码中找到一两个流程的必经之地, 设置断点, 再用backtrace倒过来看WebKit是怎么跑到这个函数的.
以浏览网页最常见的一个操作为例, 点击链接打开新页面. 事件的传播流程如下:
- (gdb) bt
- #0 WebCore::RenderBlock::nodeAtPoint (this=0x9b5ed8c, request=@0xbfec5b90, result=@0xbfec5a30, _x=171, _y=42, _tx=0, _ty=0,
- hitTestAction=WebCore::HitTestFloat) at ../../../WebCore/rendering/RenderBlock.cpp:3102
- #1 0x01a46abc in WebCore::RenderObject::hitTest (this=0x9b5ed8c, request=@0xbfec5b90, result=@0xbfec5a30, point=@0xbfec59f0, tx=0, ty=0,
- hitTestFilter=WebCore::HitTestDescendants) at ../../../WebCore/rendering/RenderObject.cpp:2705
- #2 0x01a32036 in WebCore::RenderLayer::hitTestLayer (this=0x9b56fec, rootLayer=0x9bd6be4, request=@0xbfec5b90, result=@0xbfec5a30,
- hitTestRect=@0xbfec59d0, hitTestPoint=@0xbfec59f0, appliedTransform=false) at ../../../WebCore/rendering/RenderLayer.cpp:1940
- #3 0x01a31eac in WebCore::RenderLayer::hitTestLayer (this=0x9bd6be4, rootLayer=0x9bd6be4, request=@0xbfec5b90, result=@0xbfec5a30,
- hitTestRect=@0xbfec59d0, hitTestPoint=@0xbfec59f0, appliedTransform=false) at ../../../WebCore/rendering/RenderLayer.cpp:1924
- #4 0x01a324ad in WebCore::RenderLayer::hitTest (this=0x9bd6be4, request=@0xbfec5b90, result=@0xbfec5a30)
- at ../../../WebCore/rendering/RenderLayer.cpp:1843
- #5 0x0162d225 in WebCore::Document::prepareMouseEvent (this=0x9c4c5e8, request=@0xbfec5b90, documentPoint=@0xbfec5ab8, event=@0xbfec5c8c)
- at ../../../WebCore/dom/Document.cpp:1986
- #6 0x018f129b in WebCore::EventHandler::prepareMouseEvent (this=0x9af11c8, request=@0xbfec5b90, mev=@0xbfec5c8c)
- at ../../../WebCore/page/EventHandler.cpp:1425
- #7 0x018f7f38 in WebCore::EventHandler::handleMousePressEvent (this=0x9af11c8, mouseEvent=@0xbfec5c8c) at ../../../WebCore/page/EventHandler.cpp:1006
- #8 0x01b29a5c in QWebPagePrivate::mousePressEvent (this=0x9acf438, ev=0xbfec62e0) at ../../../WebKit/qt/Api/qwebpage.cpp:527
- #9 0x01b29cbe in QWebPage::event (this=0x9acf1b0, ev=0xbfec62e0) at ../../../WebKit/qt/Api/qwebpage.cpp:1731
- #10 0x01b2fd8a in QWebView::mousePressEvent (this=0x9aec760, ev=0xbfec62e0) at ../../../WebKit/qt/Api/qwebview.cpp:715
- #11 0x002d4200 in QWidget::event (this=0x9aec760, event=0xbfec62e0) at kernel/qwidget.cpp:7159
- #12 0x01b306d2 in QWebView::event (this=0x9aec760, e=0xbfec62e0) at ../../../WebKit/qt/Api/qwebview.cpp:583
- #13 0x0027b95f in QApplicationPrivate::notify_helper (this=0x9ab3530, receiver=0x9aec760, e=0xbfec62e0) at kernel/qapplication.cpp:3803
- #14 0x002805c1 in QApplication::notify (this=0xbfec6a50, receiver=0x9aec760, e=0xbfec62e0) at kernel/qapplication.cpp:3528
- #15 0x025d82f9 in QCoreApplication::notifyInternal (this=0xbfec6a50, receiver=0x9aec760, event=0xbfec62e0) at kernel/qcoreapplication.cpp:587
- #16 0x0027e0c3 in QApplicationPrivate::sendMouseEvent (receiver=0x9aec760, event=0xbfec62e0, alienWidget=0x9aec760, nativeWidget=0xbfec69b0,
- buttonDown=0xa3c470, lastMouseReceiver=@0xa3c474) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:212
- #17 0x002e753b in QETWidget::translateMouseEvent (this=0xbfec69b0, event=0xbfec66ac) at kernel/qapplication_x11.cpp:4042
- #18 0x002e6468 in QApplication::x11ProcessEvent (this=0xbfec6a50, event=0xbfec66ac) at kernel/qapplication_x11.cpp:3160
- #19 0x0030d0eb in x11EventSourceDispatch (s=0x9abb470, callback=0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:142
- #20 0x026ef10c in g_main_context_dispatch () from /lib/libglib-2.0.so.0
- #21 0x026f254f in ?? () from /lib/libglib-2.0.so.0
- #22 0x026f2ab5 in g_main_context_iteration () from /lib/libglib-2.0.so.0
- #23 0x0260382e in QEventDispatcherGlib::processEvents (this=0x9ab8270, flags=@0xbfec68a8) at kernel/qeventdispatcher_glib.cpp:319
- #24 0x0030ced5 in QGuiEventDispatcherGlib::processEvents (this=0x9ab8270, flags=@0xbfec68d8) at kernel/qguieventdispatcher_glib.cpp:198
- #25 0x025d758d in QEventLoop::processEvents (this=0xbfec6950, flags=@0xbfec6918) at kernel/qeventloop.cpp:143
- #26 0x025d771d in QEventLoop::exec (this=0xbfec6950, flags=@0xbfec6958) at kernel/qeventloop.cpp:194
- #27 0x025d96dd in QCoreApplication::exec () at kernel/qcoreapplication.cpp:845
- #28 0x0027b257 in QApplication::exec () at kernel/qapplication.cpp:3331
- #29 0x080564a2 in main (argc=Cannot access memory at address 0x14) at /insistech/pq/webkitr39370/mini39370/WebKit/qt/QtLauncher/main.cpp:437
这个过程得到点击处的RenderObject, 如果该对象isLinke() 那么再触发打开连接的事件. 至于打开链接的流程这里先不涉及了.
Painting
相关的文件最主要的两个:
RenderTheme.h/cpp
RenderThemeQt.h/cpp
RenderTheme 是关键的一个类.
RenderThemeQt继承了它, 重载了很多虚函数, 这些虚函数用来进行具体的绘制工作比如:
- virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
- virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
- virtual void setButtonSize(RenderStyle*) const { }
以paintButton()为例, 传进去的的参数包含了:
PaintInfo: 屏幕的buffer(QPainterDevice), 相当于画布,
IntRect: 绘制的区域
在指定的区域内, 就可以用QPainter来画button了. 至于是windows风格的还是mac水晶风格的, 还是简单的画个长方体, 那就任由发挥了.
- (gdb) bt
- #0 WebCore::RenderThemeQt::paintButton (this=0x2313b48, o=0x8eb8cbc, i=@0xbf88a99c, r=@0xbf88a850) at ../../../WebCore/platform/qt/RenderThemeQt.cpp:457
- #1 0x01a88918 in WebCore::RenderTheme::paint (this=0x2313b48, o=0x8eb8cbc, paintInfo=@0xbf88a99c, r=@0xbf88a850) at ../../../WebCore/rendering/RenderTheme.cpp:242
- #2 0x01a03f8e in WebCore::RenderBox::paintBoxDecorations (this=0x8eb8cbc, paintInfo=@0xbf88a99c, tx=103, ty=201) at ../../../WebCore/rendering/RenderBox.cpp:421
- #3 0x019dfa94 in WebCore::RenderBlock::paintObject (this=0x8eb8cbc, paintInfo=@0xbf88a99c, tx=103, ty=201) at ../../../WebCore/rendering/RenderBlock.cpp:1670
- #4 0x019e019a in WebCore::RenderBlock::paint (this=0x8eb8cbc, paintInfo=@0xbf88a99c, tx=103, ty=201) at ../../../WebCore/rendering/RenderBlock.cpp:1517
- #5 0x019c19e4 in WebCore::InlineBox::paint (this=0x8d61f44, paintInfo=@0xbf88a9f4, tx=14, ty=172) at ../../../WebCore/rendering/InlineBox.cpp:147
- #6 0x019c4cfd in WebCore::InlineFlowBox::paint (this=0x8ebbaf4, paintInfo=@0xbf88aadc, tx=14, ty=172) at ../../../WebCore/rendering/InlineFlowBox.cpp:663
- #7 0x01a9ae06 in WebCore::RootInlineBox::paint (this=0x8ebbaf4, paintInfo=@0xbf88aadc, tx=14, ty=172) at ../../../WebCore/rendering/RootInlineBox.cpp:179
- #8 0x01a1e975 in WebCore::RenderFlow::paintLines (this=0x8eb6e64, paintInfo=@0xbf88b03c, tx=14, ty=172) at ../../../WebCore/rendering/RenderFlow.cpp:434
- #9 0x019df4c0 in WebCore::RenderBlock::paintContents (this=0x8eb6e64, paintInfo=@0xbf88b03c, tx=14, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1603
- #10 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8eb6e64, paintInfo=@0xbf88b03c, tx=14, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1693
- #11 0x01a6988b in WebCore::RenderTableCell::paint (this=0x8eb6e64, paintInfo=@0xbf88b03c, tx=14, ty=172) at ../../../WebCore/rendering/RenderTableCell.cpp:649
- #12 0x01a74659 in WebCore::RenderTableSection::paint (this=0x8eb6304, paintInfo=@0xbf88b03c, tx=8, ty=172) at ../../../WebCore/rendering/RenderTableSection.cpp:970
- #13 0x01a6e33a in WebCore::RenderTable::paint (this=0x8eb5f54, paintInfo=@0xbf88b0b4, tx=8, ty=172) at ../../../WebCore/rendering/RenderTable.cpp:482
- #14 0x019df285 in WebCore::RenderBlock::paintChildren (this=0x8eb2d74, paintInfo=@0xbf88b214, tx=8, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1629
- #15 0x019df4e2 in WebCore::RenderBlock::paintContents (this=0x8eb2d74, paintInfo=@0xbf88b214, tx=8, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1605
- #16 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8eb2d74, paintInfo=@0xbf88b214, tx=8, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1693
- #17 0x019e019a in WebCore::RenderBlock::paint (this=0x8eb2d74, paintInfo=@0xbf88b214, tx=8, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1517
- #18 0x019df285 in WebCore::RenderBlock::paintChildren (this=0x8eaf7a4, paintInfo=@0xbf88b374, tx=8, ty=28) at ../../../WebCore/rendering/RenderBlock.cpp:1629
- #19 0x019df4e2 in WebCore::RenderBlock::paintContents (this=0x8eaf7a4, paintInfo=@0xbf88b374, tx=8, ty=28) at ../../../WebCore/rendering/RenderBlock.cpp:1605
- #20 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8eaf7a4, paintInfo=@0xbf88b374, tx=8, ty=28) at ../../../WebCore/rendering/RenderBlock.cpp:1693
- #21 0x019e019a in WebCore::RenderBlock::paint (this=0x8eaf7a4, paintInfo=@0xbf88b374, tx=8, ty=28) at ../../../WebCore/rendering/RenderBlock.cpp:1517
- #22 0x019df285 in WebCore::RenderBlock::paintChildren (this=0x8d4a774, paintInfo=@0xbf88b4d4, tx=8, ty=3) at ../../../WebCore/rendering/RenderBlock.cpp:1629
- #23 0x019df4e2 in WebCore::RenderBlock::paintContents (this=0x8d4a774, paintInfo=@0xbf88b4d4, tx=8, ty=3) at ../../../WebCore/rendering/RenderBlock.cpp:1605
- #24 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8d4a774, paintInfo=@0xbf88b4d4, tx=8, ty=3) at ../../../WebCore/rendering/RenderBlock.cpp:1693
- #25 0x019e019a in WebCore::RenderBlock::paint (this=0x8d4a774, paintInfo=@0xbf88b4d4, tx=8, ty=3) at ../../../WebCore/rendering/RenderBlock.cpp:1517
- #26 0x019df285 in WebCore::RenderBlock::paintChildren (this=0x8d48f34, paintInfo=@0xbf88b650, tx=0, ty=0) at ../../../WebCore/rendering/RenderBlock.cpp:1629
- #27 0x019df4e2 in WebCore::RenderBlock::paintContents (this=0x8d48f34, paintInfo=@0xbf88b650, tx=0, ty=0) at ../../../WebCore/rendering/RenderBlock.cpp:1605
- #28 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8d48f34, paintInfo=@0xbf88b650, tx=0, ty=0) at ../../../WebCore/rendering/RenderBlock.cpp:1693
- #29 0x019e019a in WebCore::RenderBlock::paint (this=0x8d48f34, paintInfo=@0xbf88b650, tx=0, ty=0) at ../../../WebCore/rendering/RenderBlock.cpp:1517
- #30 0x01a33052 in WebCore::RenderLayer::paintLayer (this=0x8d5966c, rootLayer=0x8d4cefc, p=0xbf88bab0, paintDirtyRect=@0xbf88ba08, haveTransparency=false, paintRestriction=WebCore::PaintRestrictionNone, paintingRoot=0x0, appliedTransform=false) at ../../../WebCore/rendering/RenderLayer.cpp:1781
- #31 0x01a33231 in WebCore::RenderLayer::paintLayer (this=0x8d4cefc, rootLayer=0x8d4cefc, p=0xbf88bab0, paintDirtyRect=@0xbf88ba08, haveTransparency=false, paintRestriction=WebCore::PaintRestrictionNone, paintingRoot=0x0, appliedTransform=false) at ../../../WebCore/rendering/RenderLayer.cpp:1806
- #32 0x01a3340e in WebCore::RenderLayer::paint (this=0x8d4cefc, p=0xbf88bab0, damageRect=@0xbf88ba08, paintRestriction=WebCore::PaintRestrictionNone, paintingRoot=0x0) at ../../../WebCore/rendering/RenderLayer.cpp:1623
- #33 0x0190c4fe in WebCore::FrameView::paintContents (this=0x8d90a08, p=0xbf88bab0, rect=@0xbf88ba08) at ../../../WebCore/page/FrameView.cpp:1222
- #34 0x01971a5f in WebCore::ScrollView::paint (this=0x8d90a08, context=0xbf88bab0, rect=@0xbf88bab8) at ../../../WebCore/platform/ScrollView.cpp:647
- #35 0x01b22434 in QWebFrame::render (this=0x8be9b18, painter=0xbf88bb08, clip=@0xbf88bfc0) at ../../../WebKit/qt/Api/qwebframe.cpp:741
- #36 0x01b303ce in QWebView::paintEvent (this=0x8be9758, ev=0xbf88bfa4) at ../../../WebKit/qt/Api/qwebview.cpp:678
- #37 0x002d3d33 in QWidget::event (this=0x8be9758, event=0xbf88bfa4) at kernel/qwidget.cpp:7301
- #38 0x01b306d2 in QWebView::event (this=0x8be9758, e=0xbf88bfa4) at ../../../WebKit/qt/Api/qwebview.cpp:583
- #39 0x0027b95f in QApplicationPrivate::notify_helper (this=0x8bb0530, receiver=0x8be9758, e=0xbf88bfa4) at kernel/qapplication.cpp:3803
- #40 0x0028043e in QApplication::notify (this=0xbf88cc10, receiver=0x8be9758, e=0xbf88bfa4) at kernel/qapplication.cpp:3768
上面是一些控件的流程, 常见的Text对象走的是另外一条路, 大概的backtrace如下:
- InlineTextBox::paint()
- GraphicsContext::drawText()
- Font::drawText()
- QPainter::drawText()
备注:
WebKit版本是r39370.
Platform: Qt
- Webkit Painting and Event Flow 绘屏和事件 探讨
- Webkit Painting and Event Flow 绘屏和事件 探讨
- AS3 event flow 事件冒泡机制
- AS3 event flow 事件冒泡机制
- AS3 event flow 事件冒泡机制
- 委托和事件之烧开水:Delegate and Event
- WebKit Event
- Actionscript 3.0 事件机制剖析--The Event Flow
- AS3 event flow 事件冒泡机制 以及 stopImmediatePropagation() stopPropagation()用法
- SAP事件 Event Flow(转 感谢原创)
- Event 事件和托管
- android 4.0.1 webkit Event 事件处理过程分析
- android 4.0.1 webkit Event 事件处理过程分析
- webkit 添加自定义事件接口发送自定义Event
- 委托(delegate)和事件(event)
- Delegate委托 和 Event事件
- HTML5中的新标签和新事件属性(Tags and Event Attributes)
- Event事件之剪贴板和拖动事件
- 浏览器探究——webkit部分——Button
- 推荐十大国外IT网站
- 初涉USB,初学者USB入门总结(3) 数据包阐述
- [ACM] ACM常见错误
- cocos2dx 响应windows键盘事件
- Webkit Painting and Event Flow 绘屏和事件 探讨
- XML解析( Dom4j 详解)
- windows系统上安装与使用Android NDK
- 初涉USB,初学者USB入门总结4,USB通讯设备快速开发
- mac与windows 共享设置
- 初涉USB,初学者USB入门总结(5)USB上位机读写开发
- Android系统移植与调试之------->深入理解Android Sensor系统 (4.0)
- JSP页面打印
- 霜波说测试(1)-----优秀的测试用例