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是怎么跑到这个函数的.

 

以浏览网页最常见的一个操作为例, 点击链接打开新页面. 事件的传播流程如下:

 

[cpp] view plaincopy
  1. (gdb) bt  
  2. #0  WebCore::RenderBlock::nodeAtPoint (this=0x9b5ed8c, request=@0xbfec5b90, result=@0xbfec5a30, _x=171, _y=42, _tx=0, _ty=0,  
  3.     hitTestAction=WebCore::HitTestFloat) at ../../../WebCore/rendering/RenderBlock.cpp:3102  
  4. #1  0x01a46abc in WebCore::RenderObject::hitTest (this=0x9b5ed8c, request=@0xbfec5b90, result=@0xbfec5a30, point=@0xbfec59f0, tx=0, ty=0,  
  5.     hitTestFilter=WebCore::HitTestDescendants) at ../../../WebCore/rendering/RenderObject.cpp:2705  
  6. #2  0x01a32036 in WebCore::RenderLayer::hitTestLayer (this=0x9b56fec, rootLayer=0x9bd6be4, request=@0xbfec5b90, result=@0xbfec5a30,  
  7.     hitTestRect=@0xbfec59d0, hitTestPoint=@0xbfec59f0, appliedTransform=false) at ../../../WebCore/rendering/RenderLayer.cpp:1940  
  8. #3  0x01a31eac in WebCore::RenderLayer::hitTestLayer (this=0x9bd6be4, rootLayer=0x9bd6be4, request=@0xbfec5b90, result=@0xbfec5a30,  
  9.     hitTestRect=@0xbfec59d0, hitTestPoint=@0xbfec59f0, appliedTransform=false) at ../../../WebCore/rendering/RenderLayer.cpp:1924  
  10. #4  0x01a324ad in WebCore::RenderLayer::hitTest (this=0x9bd6be4, request=@0xbfec5b90, result=@0xbfec5a30)  
  11.     at ../../../WebCore/rendering/RenderLayer.cpp:1843  
  12. #5  0x0162d225 in WebCore::Document::prepareMouseEvent (this=0x9c4c5e8, request=@0xbfec5b90, documentPoint=@0xbfec5ab8, event=@0xbfec5c8c)  
  13.     at ../../../WebCore/dom/Document.cpp:1986  
  14. #6  0x018f129b in WebCore::EventHandler::prepareMouseEvent (this=0x9af11c8, request=@0xbfec5b90, mev=@0xbfec5c8c)  
  15.     at ../../../WebCore/page/EventHandler.cpp:1425  
  16. #7  0x018f7f38 in WebCore::EventHandler::handleMousePressEvent (this=0x9af11c8, mouseEvent=@0xbfec5c8c) at ../../../WebCore/page/EventHandler.cpp:1006  
  17. #8  0x01b29a5c in QWebPagePrivate::mousePressEvent (this=0x9acf438, ev=0xbfec62e0) at ../../../WebKit/qt/Api/qwebpage.cpp:527  
  18. #9  0x01b29cbe in QWebPage::event (this=0x9acf1b0, ev=0xbfec62e0) at ../../../WebKit/qt/Api/qwebpage.cpp:1731  
  19. #10 0x01b2fd8a in QWebView::mousePressEvent (this=0x9aec760, ev=0xbfec62e0) at ../../../WebKit/qt/Api/qwebview.cpp:715  
  20. #11 0x002d4200 in QWidget::event (this=0x9aec760, event=0xbfec62e0) at kernel/qwidget.cpp:7159  
  21. #12 0x01b306d2 in QWebView::event (this=0x9aec760, e=0xbfec62e0) at ../../../WebKit/qt/Api/qwebview.cpp:583  
  22. #13 0x0027b95f in QApplicationPrivate::notify_helper (this=0x9ab3530, receiver=0x9aec760, e=0xbfec62e0) at kernel/qapplication.cpp:3803  
  23. #14 0x002805c1 in QApplication::notify (this=0xbfec6a50, receiver=0x9aec760, e=0xbfec62e0) at kernel/qapplication.cpp:3528  
  24. #15 0x025d82f9 in QCoreApplication::notifyInternal (this=0xbfec6a50, receiver=0x9aec760, event=0xbfec62e0) at kernel/qcoreapplication.cpp:587  
  25. #16 0x0027e0c3 in QApplicationPrivate::sendMouseEvent (receiver=0x9aec760, event=0xbfec62e0, alienWidget=0x9aec760, nativeWidget=0xbfec69b0,  
  26.     buttonDown=0xa3c470, lastMouseReceiver=@0xa3c474) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:212  
  27. #17 0x002e753b in QETWidget::translateMouseEvent (this=0xbfec69b0, event=0xbfec66ac) at kernel/qapplication_x11.cpp:4042  
  28. #18 0x002e6468 in QApplication::x11ProcessEvent (this=0xbfec6a50, event=0xbfec66ac) at kernel/qapplication_x11.cpp:3160  
  29. #19 0x0030d0eb in x11EventSourceDispatch (s=0x9abb470, callback=0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:142  
  30. #20 0x026ef10c in g_main_context_dispatch () from /lib/libglib-2.0.so.0  
  31. #21 0x026f254f in ?? () from /lib/libglib-2.0.so.0  
  32. #22 0x026f2ab5 in g_main_context_iteration () from /lib/libglib-2.0.so.0  
  33. #23 0x0260382e in QEventDispatcherGlib::processEvents (this=0x9ab8270, flags=@0xbfec68a8) at kernel/qeventdispatcher_glib.cpp:319  
  34. #24 0x0030ced5 in QGuiEventDispatcherGlib::processEvents (this=0x9ab8270, flags=@0xbfec68d8) at kernel/qguieventdispatcher_glib.cpp:198  
  35. #25 0x025d758d in QEventLoop::processEvents (this=0xbfec6950, flags=@0xbfec6918) at kernel/qeventloop.cpp:143  
  36. #26 0x025d771d in QEventLoop::exec (this=0xbfec6950, flags=@0xbfec6958) at kernel/qeventloop.cpp:194  
  37. #27 0x025d96dd in QCoreApplication::exec () at kernel/qcoreapplication.cpp:845  
  38. #28 0x0027b257 in QApplication::exec () at kernel/qapplication.cpp:3331  
  39. #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继承了它, 重载了很多虚函数, 这些虚函数用来进行具体的绘制工作比如:

[cpp] view plaincopy
  1. virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;  
  2. virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }  
  3. virtual void setButtonSize(RenderStyle*) const { }  


以paintButton()为例, 传进去的的参数包含了:
PaintInfo: 屏幕的buffer(QPainterDevice), 相当于画布,
IntRect: 绘制的区域
在指定的区域内, 就可以用QPainter来画button了. 至于是windows风格的还是mac水晶风格的, 还是简单的画个长方体, 那就任由发挥了.

 

[cpp] view plaincopy
  1. (gdb) bt  
  2. #0  WebCore::RenderThemeQt::paintButton (this=0x2313b48, o=0x8eb8cbc, i=@0xbf88a99c, r=@0xbf88a850) at ../../../WebCore/platform/qt/RenderThemeQt.cpp:457  
  3. #1  0x01a88918 in WebCore::RenderTheme::paint (this=0x2313b48, o=0x8eb8cbc, paintInfo=@0xbf88a99c, r=@0xbf88a850) at ../../../WebCore/rendering/RenderTheme.cpp:242  
  4. #2  0x01a03f8e in WebCore::RenderBox::paintBoxDecorations (this=0x8eb8cbc, paintInfo=@0xbf88a99c, tx=103, ty=201) at ../../../WebCore/rendering/RenderBox.cpp:421  
  5. #3  0x019dfa94 in WebCore::RenderBlock::paintObject (this=0x8eb8cbc, paintInfo=@0xbf88a99c, tx=103, ty=201) at ../../../WebCore/rendering/RenderBlock.cpp:1670  
  6. #4  0x019e019a in WebCore::RenderBlock::paint (this=0x8eb8cbc, paintInfo=@0xbf88a99c, tx=103, ty=201) at ../../../WebCore/rendering/RenderBlock.cpp:1517  
  7. #5  0x019c19e4 in WebCore::InlineBox::paint (this=0x8d61f44, paintInfo=@0xbf88a9f4, tx=14, ty=172) at ../../../WebCore/rendering/InlineBox.cpp:147  
  8. #6  0x019c4cfd in WebCore::InlineFlowBox::paint (this=0x8ebbaf4, paintInfo=@0xbf88aadc, tx=14, ty=172) at ../../../WebCore/rendering/InlineFlowBox.cpp:663  
  9. #7  0x01a9ae06 in WebCore::RootInlineBox::paint (this=0x8ebbaf4, paintInfo=@0xbf88aadc, tx=14, ty=172) at ../../../WebCore/rendering/RootInlineBox.cpp:179  
  10. #8  0x01a1e975 in WebCore::RenderFlow::paintLines (this=0x8eb6e64, paintInfo=@0xbf88b03c, tx=14, ty=172) at ../../../WebCore/rendering/RenderFlow.cpp:434  
  11. #9  0x019df4c0 in WebCore::RenderBlock::paintContents (this=0x8eb6e64, paintInfo=@0xbf88b03c, tx=14, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1603  
  12. #10 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8eb6e64, paintInfo=@0xbf88b03c, tx=14, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1693  
  13. #11 0x01a6988b in WebCore::RenderTableCell::paint (this=0x8eb6e64, paintInfo=@0xbf88b03c, tx=14, ty=172) at ../../../WebCore/rendering/RenderTableCell.cpp:649  
  14. #12 0x01a74659 in WebCore::RenderTableSection::paint (this=0x8eb6304, paintInfo=@0xbf88b03c, tx=8, ty=172) at ../../../WebCore/rendering/RenderTableSection.cpp:970  
  15. #13 0x01a6e33a in WebCore::RenderTable::paint (this=0x8eb5f54, paintInfo=@0xbf88b0b4, tx=8, ty=172) at ../../../WebCore/rendering/RenderTable.cpp:482  
  16. #14 0x019df285 in WebCore::RenderBlock::paintChildren (this=0x8eb2d74, paintInfo=@0xbf88b214, tx=8, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1629  
  17. #15 0x019df4e2 in WebCore::RenderBlock::paintContents (this=0x8eb2d74, paintInfo=@0xbf88b214, tx=8, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1605  
  18. #16 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8eb2d74, paintInfo=@0xbf88b214, tx=8, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1693  
  19. #17 0x019e019a in WebCore::RenderBlock::paint (this=0x8eb2d74, paintInfo=@0xbf88b214, tx=8, ty=172) at ../../../WebCore/rendering/RenderBlock.cpp:1517  
  20. #18 0x019df285 in WebCore::RenderBlock::paintChildren (this=0x8eaf7a4, paintInfo=@0xbf88b374, tx=8, ty=28) at ../../../WebCore/rendering/RenderBlock.cpp:1629  
  21. #19 0x019df4e2 in WebCore::RenderBlock::paintContents (this=0x8eaf7a4, paintInfo=@0xbf88b374, tx=8, ty=28) at ../../../WebCore/rendering/RenderBlock.cpp:1605  
  22. #20 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8eaf7a4, paintInfo=@0xbf88b374, tx=8, ty=28) at ../../../WebCore/rendering/RenderBlock.cpp:1693  
  23. #21 0x019e019a in WebCore::RenderBlock::paint (this=0x8eaf7a4, paintInfo=@0xbf88b374, tx=8, ty=28) at ../../../WebCore/rendering/RenderBlock.cpp:1517  
  24. #22 0x019df285 in WebCore::RenderBlock::paintChildren (this=0x8d4a774, paintInfo=@0xbf88b4d4, tx=8, ty=3) at ../../../WebCore/rendering/RenderBlock.cpp:1629  
  25. #23 0x019df4e2 in WebCore::RenderBlock::paintContents (this=0x8d4a774, paintInfo=@0xbf88b4d4, tx=8, ty=3) at ../../../WebCore/rendering/RenderBlock.cpp:1605  
  26. #24 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8d4a774, paintInfo=@0xbf88b4d4, tx=8, ty=3) at ../../../WebCore/rendering/RenderBlock.cpp:1693  
  27. #25 0x019e019a in WebCore::RenderBlock::paint (this=0x8d4a774, paintInfo=@0xbf88b4d4, tx=8, ty=3) at ../../../WebCore/rendering/RenderBlock.cpp:1517  
  28. #26 0x019df285 in WebCore::RenderBlock::paintChildren (this=0x8d48f34, paintInfo=@0xbf88b650, tx=0, ty=0) at ../../../WebCore/rendering/RenderBlock.cpp:1629  
  29. #27 0x019df4e2 in WebCore::RenderBlock::paintContents (this=0x8d48f34, paintInfo=@0xbf88b650, tx=0, ty=0) at ../../../WebCore/rendering/RenderBlock.cpp:1605  
  30. #28 0x019dfb90 in WebCore::RenderBlock::paintObject (this=0x8d48f34, paintInfo=@0xbf88b650, tx=0, ty=0) at ../../../WebCore/rendering/RenderBlock.cpp:1693  
  31. #29 0x019e019a in WebCore::RenderBlock::paint (this=0x8d48f34, paintInfo=@0xbf88b650, tx=0, ty=0) at ../../../WebCore/rendering/RenderBlock.cpp:1517  
  32. #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  
  33. #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  
  34. #32 0x01a3340e in WebCore::RenderLayer::paint (this=0x8d4cefc, p=0xbf88bab0, damageRect=@0xbf88ba08, paintRestriction=WebCore::PaintRestrictionNone, paintingRoot=0x0) at ../../../WebCore/rendering/RenderLayer.cpp:1623  
  35. #33 0x0190c4fe in WebCore::FrameView::paintContents (this=0x8d90a08, p=0xbf88bab0, rect=@0xbf88ba08) at ../../../WebCore/page/FrameView.cpp:1222  
  36. #34 0x01971a5f in WebCore::ScrollView::paint (this=0x8d90a08, context=0xbf88bab0, rect=@0xbf88bab8) at ../../../WebCore/platform/ScrollView.cpp:647  
  37. #35 0x01b22434 in QWebFrame::render (this=0x8be9b18, painter=0xbf88bb08, clip=@0xbf88bfc0) at ../../../WebKit/qt/Api/qwebframe.cpp:741  
  38. #36 0x01b303ce in QWebView::paintEvent (this=0x8be9758, ev=0xbf88bfa4) at ../../../WebKit/qt/Api/qwebview.cpp:678  
  39. #37 0x002d3d33 in QWidget::event (this=0x8be9758, event=0xbf88bfa4) at kernel/qwidget.cpp:7301  
  40. #38 0x01b306d2 in QWebView::event (this=0x8be9758, e=0xbf88bfa4) at ../../../WebKit/qt/Api/qwebview.cpp:583  
  41. #39 0x0027b95f in QApplicationPrivate::notify_helper (this=0x8bb0530, receiver=0x8be9758, e=0xbf88bfa4) at kernel/qapplication.cpp:3803  
  42. #40 0x0028043e in QApplication::notify (this=0xbf88cc10, receiver=0x8be9758, e=0xbf88bfa4) at kernel/qapplication.cpp:3768  

 

 



上面是一些控件的流程, 常见的Text对象走的是另外一条路, 大概的backtrace如下:

[cpp] view plaincopy
  1. InlineTextBox::paint()  
  2. GraphicsContext::drawText()  
  3. Font::drawText()  
  4. QPainter::drawText()   

 

 

备注:

WebKit版本是r39370.

Platform: Qt