Advertisement
diogogmt

Inspecting MouseEvent - stack trace

Feb 29th, 2012
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.85 KB | None | 0 0
  1. #17 0x00007ffd712eeaed in nsWindow::DispatchEvent (this=0x7ffd5cb37600, aEvent=0x7fff47ee2ce0, aStatus=@0x7fff47ee2d6c)
  2. at /home/diogogmt/mozilla-central-diogogmt/widget/gtk2/nsWindow.cpp:575
  3.  
  4. 563 nsresult
  5. 564 nsWindow::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus)
  6. 565 {
  7. 566 #ifdef DEBUG
  8. 567 debug_DumpEvent(stdout, aEvent->widget, aEvent,
  9. 568 nsCAutoString("something"), 0);
  10. 569 #endif
  11. 570
  12. 571 aStatus = nsEventStatus_eIgnore;
  13. 572
  14. 573 // send it to the standard callback
  15. 574 if (mEventCallback)
  16. 575 aStatus = (* mEventCallback)(aEvent);
  17. 576
  18. 577 return NS_OK;
  19. 578 }
  20.  
  21.  
  22. #16 0x00007ffd708e2672 in HandleEvent (aEvent=0x7fff47ee2ce0) at /home/diogogmt/mozilla-central-diogogmt/view/src/nsView.cpp:158
  23.  
  24. 146 // Main events handler
  25. 147 static nsEventStatus HandleEvent(nsGUIEvent *aEvent)
  26. 148 {
  27. 149 #if 0
  28. 150 printf(" %d %d %d (%d,%d) \n", aEvent->widget, aEvent->message);
  29. 151 #endif
  30. 152 nsEventStatus result = nsEventStatus_eIgnore;
  31. 153 nsView *view = nsView::GetViewFor(aEvent->widget);
  32. 154
  33. 155 if (view)
  34. 156 {
  35. 157 nsCOMPtr<nsIViewManager> vm = view->GetViewManager();
  36. 158 vm->DispatchEvent(aEvent, view, &result);
  37. 159 }
  38. 160
  39. 161 return result;
  40. 162 }
  41.  
  42.  
  43.  
  44. #15 0x00007ffd708e871d in nsViewManager::DispatchEvent (this=0x7ffd5cba8bf0, aEvent=0x7fff47ee2ce0, aView=0x7ffd5cb77600, aStatus=0x7fff47ee2c14)
  45. at /home/diogogmt/mozilla-central-diogogmt/view/src/nsViewManager.cpp:908
  46.  
  47. 652 NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
  48. 653 nsIView* aView, nsEventStatus *aStatus)
  49. 654 {
  50. 655 NS_ASSERTION(!aView || static_cast<nsView*>(aView)->GetViewManager() == this,
  51. 656 "wrong view manager");
  52. 657
  53. 658 SAMPLE_LABEL("event", "nsViewManager::DispatchEvent");
  54. 659
  55. 660 *aStatus = nsEventStatus_eIgnore;
  56. 661
  57. 662 switch(aEvent->message)
  58. 663 {
  59. 664 case NS_SIZE:
  60. 665 {
  61. 666 if (aView)
  62. 667 {
  63. 668 // client area dimensions are set on the view
  64. 669 nscoord width = ((nsSizeEvent*)aEvent)->windowSize->width;
  65. 670 nscoord height = ((nsSizeEvent*)aEvent)->windowSize->height;
  66. 671
  67. 672 // The root view may not be set if this is the resize associated with
  68. 673 // window creation
  69. 674
  70. 675 if (aView == mRootView)
  71. 676 {
  72. 677 PRInt32 p2a = AppUnitsPerDevPixel();
  73. 678 SetWindowDimensions(NSIntPixelsToAppUnits(width, p2a),
  74. 679 NSIntPixelsToAppUnits(height, p2a));
  75. 680 *aStatus = nsEventStatus_eConsumeNoDefault;
  76. 681 }
  77. 682 else if (IsViewForPopup(aView))
  78. 683 {
  79. 684 nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
  80. 685 if (pm)
  81. 686 {
  82. 687 pm->PopupResized(aView->GetFrame(), nsIntSize(width, height));
  83. 688 *aStatus = nsEventStatus_eConsumeNoDefault;
  84. 689 }
  85. 690 }
  86. 691 }
  87. 692 }
  88. 693
  89. 694 break;
  90. 695
  91. 696 case NS_MOVE:
  92. 697 {
  93. 698 // A popup's parent view is the root view for the parent window, so when
  94. 699 // a popup moves, the popup's frame and view position must be updated
  95. 700 // to match.
  96. 701 if (aView && IsViewForPopup(aView))
  97. 702 {
  98. 703 nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
  99. 704 if (pm)
  100. 705 {
  101. 706 pm->PopupMoved(aView->GetFrame(), aEvent->refPoint);
  102. 707 *aStatus = nsEventStatus_eConsumeNoDefault;
  103. 708 }
  104. 709 }
  105. 710 break;
  106. 711 }
  107. 712
  108. 713 case NS_DONESIZEMOVE:
  109. 714 {
  110. 715 if (mPresShell) {
  111. 716 nsPresContext* presContext = mPresShell->GetPresContext();
  112. 717 if (presContext) {
  113. 718 nsEventStateManager::ClearGlobalActiveContent(nsnull);
  114. 719 }
  115. 720
  116. 721 }
  117. 722
  118. 723 nsIPresShell::ClearMouseCapture(nsnull);
  119. 724 }
  120. 725 break;
  121. 726
  122. 727 case NS_XUL_CLOSE:
  123. 728 {
  124. 729 // if this is a popup, make a request to hide it. Note that a popuphidden
  125. 730 // event listener may cancel the event and the popup will not be hidden.
  126. 731 nsIWidget* widget = aView->GetWidget();
  127. 732 if (widget) {
  128. 733 nsWindowType type;
  129. 734 widget->GetWindowType(type);
  130. 735 if (type == eWindowType_popup) {
  131. 736 nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
  132. 737 if (pm) {
  133. 738 pm->HidePopup(aView->GetFrame());
  134. 739 *aStatus = nsEventStatus_eConsumeNoDefault;
  135. 740 }
  136. 741 }
  137. 742 }
  138. 743 }
  139. 744 break;
  140. 745
  141. 746 case NS_WILL_PAINT:
  142. 747 {
  143. 748 if (!aView || !mContext)
  144. 749 break;
  145. 750
  146. 751 *aStatus = nsEventStatus_eConsumeNoDefault;
  147. 752
  148. 753 nsPaintEvent *event = static_cast<nsPaintEvent*>(aEvent);
  149. 754
  150. 755 NS_ASSERTION(static_cast<nsView*>(aView) ==
  151. 756 nsView::GetViewFor(event->widget),
  152. 757 "view/widget mismatch");
  153. 758
  154. 759 // If an ancestor widget was hidden and then shown, we could
  155. 760 // have a delayed resize to handle.
  156. 761 for (nsViewManager *vm = this; vm;
  157. 762 vm = vm->mRootView->GetParent()
  158. 763 ? vm->mRootView->GetParent()->GetViewManager()
  159. 764 : nsnull) {
  160. 765 if (vm->mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
  161. 766 vm->mRootView->IsEffectivelyVisible() &&
  162. 767 mPresShell && mPresShell->IsVisible()) {
  163. 768 vm->FlushDelayedResize(true);
  164. 769 vm->InvalidateView(vm->mRootView);
  165. 770 }
  166. 771 }
  167. 772
  168. 773 // Flush things like reflows and plugin widget geometry updates by
  169. 774 // calling WillPaint on observer presShells.
  170. 775 nsRefPtr<nsViewManager> rootVM = RootViewManager();
  171. 776 if (mPresShell) {
  172. 777 rootVM->CallWillPaintOnObservers(event->willSendDidPaint);
  173. 778 }
  174. 779 // Flush view widget geometry updates and invalidations.
  175. 780 rootVM->ProcessPendingUpdates();
  176. 781 }
  177. 782 break;
  178. 783
  179. 784 case NS_PAINT:
  180. 785 {
  181. 786 if (!aView || !mContext)
  182. 787 break;
  183. 788
  184. 789 *aStatus = nsEventStatus_eConsumeNoDefault;
  185. 790 nsPaintEvent *event = static_cast<nsPaintEvent*>(aEvent);
  186. 791 nsView* view = static_cast<nsView*>(aView);
  187. 792 NS_ASSERTION(view == nsView::GetViewFor(event->widget),
  188. 793 "view/widget mismatch");
  189. 794 NS_ASSERTION(IsPaintingAllowed(),
  190. 795 "shouldn't be receiving paint events while painting is "
  191. 796 "disallowed!");
  192. 797
  193. 798 if (!event->didSendWillPaint) {
  194. 799 // Send NS_WILL_PAINT event ourselves.
  195. 800 nsPaintEvent willPaintEvent(true, NS_WILL_PAINT, event->widget);
  196. 801 willPaintEvent.willSendDidPaint = event->willSendDidPaint;
  197. 802 DispatchEvent(&willPaintEvent, view, aStatus);
  198. 803
  199. 804 // Get the view pointer again since NS_WILL_PAINT might have
  200. 805 // destroyed it during CallWillPaintOnObservers (bug 378273).
  201. 806 view = nsView::GetViewFor(event->widget);
  202. 807 }
  203. 808
  204. 809 if (!view || event->region.IsEmpty())
  205. 810 break;
  206. 811
  207. 812 // Paint.
  208. 813 Refresh(view, event->widget, event->region, event->willSendDidPaint);
  209. 814
  210. 815 break;
  211. 816 }
  212. 817
  213. 818 case NS_DID_PAINT: {
  214. 819 nsRefPtr<nsViewManager> rootVM = RootViewManager();
  215. 820 rootVM->CallDidPaintOnObserver();
  216. 821 break;
  217. 822 }
  218. 823
  219. 824 case NS_CREATE:
  220. 825 case NS_DESTROY:
  221. 826 case NS_SETZLEVEL:
  222. 827 /* Don't pass these events through. Passing them through
  223. 828 causes performance problems on pages with lots of views/frames
  224. 829 @see bug 112861 */
  225. 830 *aStatus = nsEventStatus_eConsumeNoDefault;
  226. 831 break;
  227. 832
  228. 833 case NS_DISPLAYCHANGED:
  229. 834
  230. 835 //Destroy the cached backbuffer to force a new backbuffer
  231. 836 //be constructed with the appropriate display depth.
  232. 837 //@see bugzilla bug 6061
  233. 838 *aStatus = nsEventStatus_eConsumeDoDefault;
  234. 839 break;
  235. 840
  236. 841 case NS_SYSCOLORCHANGED:
  237. 842 {
  238. 843 if (mPresShell) {
  239. 844 // Hold a refcount to the presshell. The continued existence of the observer will
  240. 845 // delay deletion of this view hierarchy should the event want to cause its
  241. 846 // destruction in, say, some JavaScript event handler.
  242. 847 nsCOMPtr<nsIPresShell> presShell = mPresShell;
  243. 848 presShell->HandleEvent(aView->GetFrame(), aEvent, false, aStatus);
  244. 849 }
  245. 850 }
  246. 851 break;
  247. 852
  248. 853 default:
  249. 854 {
  250. 855 if ((NS_IS_MOUSE_EVENT(aEvent) &&
  251. 856 // Ignore mouse events that we synthesize.
  252. 857 static_cast<nsMouseEvent*>(aEvent)->reason ==
  253. 858 nsMouseEvent::eReal &&
  254. 859 // Ignore mouse exit and enter (we'll get moves if the user
  255. 860 // is really moving the mouse) since we get them when we
  256. 861 // create and destroy widgets.
  257. 862 aEvent->message != NS_MOUSE_EXIT &&
  258. 863 aEvent->message != NS_MOUSE_ENTER) ||
  259. 864 NS_IS_KEY_EVENT(aEvent) ||
  260. 865 NS_IS_IME_EVENT(aEvent) ||
  261. 866 aEvent->message == NS_PLUGIN_INPUT_EVENT) {
  262. 867 gLastUserEventTime = PR_IntervalToMicroseconds(PR_IntervalNow());
  263. 868 }
  264. 869
  265. 870 if (aEvent->message == NS_DEACTIVATE) {
  266. 871 // if a window is deactivated, clear the mouse capture regardless
  267. 872 // of what is capturing
  268. 873 nsIPresShell::ClearMouseCapture(nsnull);
  269. 874 }
  270. 875
  271. 876 // Find the view whose coordinates system we're in.
  272. 877 nsIView* view = aView;
  273. 878 bool dispatchUsingCoordinates = NS_IsEventUsingCoordinates(aEvent);
  274. 879 if (dispatchUsingCoordinates) {
  275. 880 // Will dispatch using coordinates. Pretty bogus but it's consistent
  276. 881 // with what presshell does.
  277. 882 view = GetDisplayRootFor(view);
  278. 883 }
  279. 884
  280. 885 // If the view has no frame, look for a view that does.
  281. 886 nsIFrame* frame = view->GetFrame();
  282. 887 if (!frame &&
  283. 888 (dispatchUsingCoordinates || NS_IS_KEY_EVENT(aEvent) ||
  284. 889 NS_IS_IME_RELATED_EVENT(aEvent) ||
  285. 890 NS_IS_NON_RETARGETED_PLUGIN_EVENT(aEvent) ||
  286. 891 aEvent->message == NS_PLUGIN_ACTIVATE ||
  287. 892 aEvent->message == NS_PLUGIN_FOCUS)) {
  288. 893 while (view && !view->GetFrame()) {
  289. 894 view = view->GetParent();
  290. 895 }
  291. 896
  292. 897 if (view) {
  293. 898 frame = view->GetFrame();
  294. 899 }
  295. 900 }
  296. 901
  297. 902 if (nsnull != frame) {
  298. 903 // Hold a refcount to the presshell. The continued existence of the
  299. 904 // presshell will delay deletion of this view hierarchy should the event
  300. 905 // want to cause its destruction in, say, some JavaScript event handler.
  301. 906 nsCOMPtr<nsIPresShell> shell = view->GetViewManager()->GetPresShell();
  302. 907 if (shell) {
  303. 908 shell->HandleEvent(frame, aEvent, false, aStatus);
  304. 909 }
  305. 910 }
  306. 911
  307. 912 break;
  308. 913 }
  309. 914 }
  310. 915
  311. 916 return NS_OK;
  312. 917 }
  313.  
  314.  
  315.  
  316. #14 0x00007ffd7021c9ca in PresShell::HandleEvent (this=0x7ffd5cb5a000, aFrame=0x7ffd5d52bc38, aEvent=0x7fff47ee2ce0, aDontRetargetEvents=false,
  317. aEventStatus=0x7fff47ee2c14) at /home/diogogmt/mozilla-central-diogogmt/layout/base/nsPresShell.cpp:6151
  318.  
  319.  
  320. 5800 nsresult
  321. 5801 PresShell::HandleEvent(nsIFrame *aFrame,
  322. 5802 nsGUIEvent* aEvent,
  323. 5803 bool aDontRetargetEvents,
  324. 5804 nsEventStatus* aEventStatus)
  325. 5805 {
  326. 5806 NS_ASSERTION(aFrame, "null frame");
  327. 5807
  328. 5808 if (mIsDestroying ||
  329. 5809 (sDisableNonTestMouseEvents && NS_IS_MOUSE_EVENT(aEvent) &&
  330. 5810 !(aEvent->flags & NS_EVENT_FLAG_SYNTHETIC_TEST_EVENT))) {
  331. 5811 return NS_OK;
  332. 5812 }
  333. 5813
  334. 5814 RecordMouseLocation(aEvent);
  335. 5815
  336. 5816 #ifdef ACCESSIBILITY
  337. 5817 if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT) {
  338. 5818 NS_TIME_FUNCTION_MIN(1.0);
  339. 5819
  340. 5820 // Accessibility events come through OS requests and not from scripts,
  341. 5821 // so it is safe to handle here
  342. 5822 return HandleEventInternal(aEvent, aEventStatus);
  343. 5823 }
  344. 5824 #endif
  345. 5825
  346. 5826 if (!nsContentUtils::IsSafeToRunScript())
  347. 5827 return NS_OK;
  348. 5828
  349. 5829 NS_TIME_FUNCTION_MIN(1.0);
  350. 5830
  351. 5831 nsIContent* capturingContent =
  352. 5832 NS_IS_MOUSE_EVENT(aEvent) ? GetCapturingContent() : nsnull;
  353. 5833
  354. 5834 nsCOMPtr<nsIDocument> retargetEventDoc;
  355. 5835 if (!aDontRetargetEvents) {
  356. 5836 // key and IME related events should not cross top level window boundary.
  357. 5837 // Basically, such input events should be fired only on focused widget.
  358. 5838 // However, some IMEs might need to clean up composition after focused
  359. 5839 // window is deactivated. And also some tests on MozMill want to test key
  360. 5840 // handling on deactivated window because MozMill window can be activated
  361. 5841 // during tests. So, there is no merit the events should be redirected to
  362. 5842 // active window. So, the events should be handled on the last focused
  363. 5843 // content in the last focused DOM window in same top level window.
  364. 5844 // Note, if no DOM window has been focused yet, we can discard the events.
  365. 5845 if (NS_IsEventTargetedAtFocusedWindow(aEvent)) {
  366. 5846 nsCOMPtr<nsPIDOMWindow> window = GetFocusedDOMWindowInOurWindow();
  367. 5847 // No DOM window in same top level window has not been focused yet,
  368. 5848 // discard the events.
  369. 5849 if (!window) {
  370. 5850 return NS_OK;
  371. 5851 }
  372. 5852
  373. 5853 retargetEventDoc = do_QueryInterface(window->GetExtantDocument());
  374. 5854 if (!retargetEventDoc)
  375. 5855 return NS_OK;
  376. 5856 } else if (capturingContent) {
  377. 5857 // if the mouse is being captured then retarget the mouse event at the
  378. 5858 // document that is being captured.
  379. 5859 retargetEventDoc = capturingContent->GetCurrentDoc();
  380. 5860 }
  381. 5861
  382. 5862 if (retargetEventDoc) {
  383. 5863 nsCOMPtr<nsIPresShell> presShell = retargetEventDoc->GetShell();
  384. 5864 if (!presShell)
  385. 5865 return NS_OK;
  386. 5866
  387. 5867 if (presShell != this) {
  388. 5868 nsIFrame* frame = presShell->GetRootFrame();
  389. 5869 if (!frame) {
  390. 5870 if (aEvent->message == NS_QUERY_TEXT_CONTENT ||
  391. 5871 NS_IS_CONTENT_COMMAND_EVENT(aEvent)) {
  392. 5872 return NS_OK;
  393. 5873 }
  394. 5874
  395. 5875 nsIView* view = presShell->GetViewManager()->GetRootView();
  396. 5876 while (view && !view->GetFrame()) {
  397. 5877 view = view->GetParent();
  398. 5878 }
  399. 5879
  400. 5880 if (view) {
  401. 5881 frame = view->GetFrame();
  402. 5882 }
  403. 5883 }
  404. 5884
  405. 5885 if (!frame)
  406. 5886 return NS_OK;
  407. 5887
  408. 5888 nsCOMPtr<nsIPresShell> shell = frame->PresContext()->GetPresShell();
  409. 5889 return shell->HandleEvent(frame, aEvent, true, aEventStatus);
  410. 5890 }
  411. 5891 }
  412. 5892 }
  413. 5893
  414. 5894 // Check for a theme change up front, since the frame type is irrelevant
  415. 5895 if (aEvent->message == NS_THEMECHANGED && mPresContext) {
  416. 5896 mPresContext->ThemeChanged();
  417. 5897 return NS_OK;
  418. 5898 }
  419. 5899
  420. 5900 if (aEvent->message == NS_UISTATECHANGED && mDocument) {
  421. 5901 nsPIDOMWindow* win = mDocument->GetWindow();
  422. 5902 if (win) {
  423. 5903 nsUIStateChangeEvent* event = (nsUIStateChangeEvent*)aEvent;
  424. 5904 win->SetKeyboardIndicators(event->showAccelerators, event->showFocusRings);
  425. 5905 }
  426. 5906 return NS_OK;
  427. 5907 }
  428. 5908
  429. 5909 // Check for a system color change up front, since the frame type is
  430. 5910 // irrelevant
  431. 5911 if ((aEvent->message == NS_SYSCOLORCHANGED) && mPresContext &&
  432. 5912 aFrame == FrameManager()->GetRootFrame()) {
  433. 5913 *aEventStatus = nsEventStatus_eConsumeDoDefault;
  434. 5914 mPresContext->SysColorChanged();
  435. 5915 return NS_OK;
  436. 5916 }
  437. 5917
  438. 5918 if (aEvent->eventStructType == NS_KEY_EVENT &&
  439. 5919 mDocument && mDocument->EventHandlingSuppressed()) {
  440. 5920 if (aEvent->message == NS_KEY_DOWN) {
  441. 5921 mNoDelayedKeyEvents = true;
  442. 5922 } else if (!mNoDelayedKeyEvents) {
  443. 5923 nsDelayedEvent* event =
  444. 5924 new nsDelayedKeyEvent(static_cast<nsKeyEvent*>(aEvent));
  445. 5925 if (!mDelayedEvents.AppendElement(event)) {
  446. 5926 delete event;
  447. 5927 }
  448. 5928 }
  449. 5929 return NS_OK;
  450. 5930 }
  451. 5931
  452. 5932 nsIFrame* frame = aFrame;
  453. 5933 bool dispatchUsingCoordinates = NS_IsEventUsingCoordinates(aEvent);
  454. 5934 if (dispatchUsingCoordinates) {
  455. 5935 NS_WARN_IF_FALSE(frame, "Nothing to handle this event!");
  456. 5936 if (!frame)
  457. 5937 return NS_OK;
  458. 5938
  459. 5939 nsPresContext* framePresContext = frame->PresContext();
  460. 5940 nsPresContext* rootPresContext = framePresContext->GetRootPresContext();
  461. 5941 NS_ASSERTION(rootPresContext == mPresContext->GetRootPresContext(),
  462. 5942 "How did we end up outside the connected prescontext/viewmanager hierarchy?");
  463. 5943 // If we aren't starting our event dispatch from the root frame of the root prescontext,
  464. 5944 // then someone must be capturing the mouse. In that case we don't want to search the popup
  465. 5945 // list.
  466. 5946 if (framePresContext == rootPresContext &&
  467. 5947 frame == FrameManager()->GetRootFrame()) {
  468. 5948 nsIFrame* popupFrame =
  469. 5949 nsLayoutUtils::GetPopupFrameForEventCoordinates(rootPresContext, aEvent);
  470. 5950 // If the popupFrame is an ancestor of the 'frame', the frame should
  471. 5951 // handle the event, otherwise, the popup should handle it.
  472. 5952 if (popupFrame &&
  473. 5953 !nsContentUtils::ContentIsCrossDocDescendantOf(
  474. 5954 framePresContext->GetPresShell()->GetDocument(),
  475. 5955 popupFrame->GetContent())) {
  476. 5956 frame = popupFrame;
  477. 5957 }
  478. 5958 }
  479. 5959
  480. 5960 bool captureRetarget = false;
  481. 5961 if (capturingContent) {
  482. 5962 // If a capture is active, determine if the docshell is visible. If not,
  483. 5963 // clear the capture and target the mouse event normally instead. This
  484. 5964 // would occur if the mouse button is held down while a tab change occurs.
  485. 5965 // If the docshell is visible, look for a scrolling container.
  486. 5966 bool vis;
  487. 5967 nsCOMPtr<nsISupports> supports = mPresContext->GetContainer();
  488. 5968 nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(supports));
  489. 5969 if (baseWin && NS_SUCCEEDED(baseWin->GetVisibility(&vis)) && vis) {
  490. 5970 captureRetarget = gCaptureInfo.mRetargetToElement;
  491. 5971 if (!captureRetarget) {
  492. 5972 // A check was already done above to ensure that capturingContent is
  493. 5973 // in this presshell.
  494. 5974 NS_ASSERTION(capturingContent->GetCurrentDoc() == GetDocument(),
  495. 5975 "Unexpected document");
  496. 5976 nsIFrame* captureFrame = capturingContent->GetPrimaryFrame();
  497. 5977 if (captureFrame) {
  498. 5978 if (capturingContent->Tag() == nsGkAtoms::select &&
  499. 5979 capturingContent->IsHTML()) {
  500. 5980 // a dropdown <select> has a child in its selectPopupList and we should
  501. 5981 // capture on that instead.
  502. 5982 nsIFrame* childFrame = captureFrame->GetChildList(nsIFrame::kSelectPopupList).FirstChild();
  503. 5983 if (childFrame) {
  504. 5984 captureFrame = childFrame;
  505. 5985 }
  506. 5986 }
  507. 5987
  508. 5988 // scrollable frames should use the scrolling container as
  509. 5989 // the root instead of the document
  510. 5990 nsIScrollableFrame* scrollFrame = do_QueryFrame(captureFrame);
  511. 5991 if (scrollFrame) {
  512. 5992 frame = scrollFrame->GetScrolledFrame();
  513. 5993 }
  514. 5994 }
  515. 5995 }
  516. 5996 }
  517. 5997 else {
  518. 5998 ClearMouseCapture(nsnull);
  519. 5999 capturingContent = nsnull;
  520. 6000 }
  521. 6001 }
  522. 6002
  523. 6003 bool isWindowLevelMouseExit = (aEvent->message == NS_MOUSE_EXIT) &&
  524. 6004 (static_cast<nsMouseEvent*>(aEvent)->exit == nsMouseEvent::eTopLevel);
  525. 6005
  526. 6006 // Get the frame at the event point. However, don't do this if we're
  527. 6007 // capturing and retargeting the event because the captured frame will
  528. 6008 // be used instead below. Also keep using the root frame if we're dealing
  529. 6009 // with a window-level mouse exit event since we want to start sending
  530. 6010 // mouse out events at the root EventStateManager.
  531. 6011 if (!captureRetarget && !isWindowLevelMouseExit) {
  532. 6012 #ifdef MOZ_TOUCH
  533. 6013 nsPoint eventPoint;
  534. 6014 if (aEvent->message == NS_TOUCH_START) {
  535. 6015 // Add any new touches to the queue
  536. 6016 nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
  537. 6017 // if there is only one touch in this touchstart event, assume that it is
  538. 6018 // the start of a new touch session and evict any old touches in the
  539. 6019 // queue
  540. 6020 if (touchEvent->touches.Length() == 1) {
  541. 6021 nsTArray<nsCOMPtr<nsIDOMTouch> > touches;
  542. 6022 gCaptureTouchList.Enumerate(&AppendToTouchList, (void *)&touches);
  543. 6023 for (PRUint32 i = 0; i < touches.Length(); ++i) {
  544. 6024 EvictTouchPoint(touches[i]);
  545. 6025 }
  546. 6026 }
  547. 6027 for (PRUint32 i = 0; i < touchEvent->touches.Length(); ++i) {
  548. 6028 nsIDOMTouch *touch = touchEvent->touches[i];
  549. 6029 nsDOMTouch *domtouch = static_cast<nsDOMTouch*>(touch);
  550. 6030 touch->mMessage = aEvent->message;
  551. 6031
  552. 6032 PRInt32 id = 0;
  553. 6033 touch->GetIdentifier(&id);
  554. 6034 if (!gCaptureTouchList.Get(id, nsnull)) {
  555. 6035 // This event is a new touch. Mark it as a changedTouch and
  556. 6036 // add it to the queue.
  557. 6037 touch->mChanged = true;
  558. 6038 gCaptureTouchList.Put(id, touch);
  559. 6039
  560. 6040 eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, touch->mRefPoint, frame);
  561. 6041 } else {
  562. 6042 // This touch is an old touch, we need to ensure that is not
  563. 6043 // marked as changed and set its target correctly
  564. 6044 touch->mChanged = false;
  565. 6045 PRInt32 id;
  566. 6046 touch->GetIdentifier(&id);
  567. 6047
  568. 6048 nsCOMPtr<nsIDOMTouch> oldTouch;
  569. 6049 gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
  570. 6050 if (oldTouch) {
  571. 6051 nsCOMPtr<nsPIDOMEventTarget> targetPtr;
  572. 6052 oldTouch->GetTarget(getter_AddRefs(targetPtr));
  573. 6053 domtouch->SetTarget(targetPtr);
  574. 6054 gCaptureTouchList.Put(id, touch);
  575. 6055 }
  576. 6056 }
  577. 6057 }
  578. 6058 } else {
  579. 6059 eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
  580. 6060 }
  581. 6061 #else
  582. 6062 nsPoint eventPoint
  583. 6063 = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
  584. 6064 #endif
  585. 6065 {
  586. 6066 bool ignoreRootScrollFrame = false;
  587. 6067 if (aEvent->eventStructType == NS_MOUSE_EVENT) {
  588. 6068 ignoreRootScrollFrame = static_cast<nsMouseEvent*>(aEvent)->ignoreRootScrollFrame;
  589. 6069 }
  590. 6070 nsIFrame* target = nsLayoutUtils::GetFrameForPoint(frame, eventPoint,
  591. 6071 false, ignoreRootScrollFrame);
  592. 6072 if (target) {
  593. 6073 frame = target;
  594. 6074 }
  595. 6075 }
  596. 6076 }
  597. 6077
  598. 6078 // if a node is capturing the mouse, check if the event needs to be
  599. 6079 // retargeted at the capturing content instead. This will be the case when
  600. 6080 // capture retargeting is being used, no frame was found or the frame's
  601. 6081 // content is not a descendant of the capturing content.
  602. 6082 if (capturingContent &&
  603. 6083 (gCaptureInfo.mRetargetToElement || !frame->GetContent() ||
  604. 6084 !nsContentUtils::ContentIsCrossDocDescendantOf(frame->GetContent(),
  605. 6085 capturingContent))) {
  606. 6086 // A check was already done above to ensure that capturingContent is
  607. 6087 // in this presshell.
  608. 6088 NS_ASSERTION(capturingContent->GetCurrentDoc() == GetDocument(),
  609. 6089 "Unexpected document");
  610. 6090 nsIFrame* capturingFrame = capturingContent->GetPrimaryFrame();
  611. 6091 if (capturingFrame) {
  612. 6092 frame = capturingFrame;
  613. 6093 }
  614. 6094 }
  615. 6095
  616. 6096 // Suppress mouse event if it's being targeted at an element inside
  617. 6097 // a document which needs events suppressed
  618. 6098 if (aEvent->eventStructType == NS_MOUSE_EVENT &&
  619. 6099 frame->PresContext()->Document()->EventHandlingSuppressed()) {
  620. 6100 if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
  621. 6101 mNoDelayedMouseEvents = true;
  622. 6102 } else if (!mNoDelayedMouseEvents && aEvent->message == NS_MOUSE_BUTTON_UP) {
  623. 6103 nsDelayedEvent* event =
  624. 6104 new nsDelayedMouseEvent(static_cast<nsMouseEvent*>(aEvent));
  625. 6105 if (!mDelayedEvents.AppendElement(event)) {
  626. 6106 delete event;
  627. 6107 }
  628. 6108 }
  629. 6109
  630. 6110 return NS_OK;
  631. 6111 }
  632. 6112
  633. 6113 PresShell* shell =
  634. 6114 static_cast<PresShell*>(frame->PresContext()->PresShell());
  635. 6115
  636. 6116 // Check if we have an active EventStateManager which isn't the6117 // EventStateManager of the current PresContext.
  637. 6118 // If that is the case, and mouse is over some ancestor document,
  638. 6119 // forward event handling to the active document.
  639. 6120 // This way content can get mouse events even when
  640. 6121 // mouse is over the chrome or outside the window.
  641. 6122 //
  642. 6123 // Note, currently for backwards compatibility we don't forward mouse events
  643. 6124 // to the active document when mouse is over some subdocument.
  644. 6125 nsEventStateManager* activeESM =
  645. 6126 nsEventStateManager::GetActiveEventStateManager();
  646. 6127 if (activeESM && NS_IS_MOUSE_EVENT(aEvent) &&
  647. 6128 activeESM != shell->GetPresContext()->EventStateManager() &&
  648. 6129 static_cast<nsEventStateManager*>(activeESM)->GetPresContext()) {
  649. 6130 nsIPresShell* activeShell =
  650. 6131 static_cast<nsEventStateManager*>(activeESM)->GetPresContext()->GetPresShell();
  651. 6132 if (activeShell &&
  652. 6133 nsContentUtils::ContentIsCrossDocDescendantOf(activeShell->GetDocument(),
  653. 6134 shell->GetDocument())) {
  654. 6135 shell = static_cast<PresShell*>(activeShell);
  655. 6136 frame = shell->GetRootFrame();
  656. 6137 }
  657. 6138 }
  658. 6139
  659. 6140 if (shell != this) {
  660. 6141 // Handle the event in the correct shell.
  661. 6142 // Prevent deletion until we're done with event handling (bug 336582).
  662. 6143 nsCOMPtr<nsIPresShell> kungFuDeathGrip(shell);
  663. 6144 // We pass the subshell's root frame as the frame to start from. This is
  664. 6145 // the only correct alternative; if the event was captured then it
  665. 6146 // must have been captured by us or some ancestor shell and we
  666. 6147 // now ask the subshell to dispatch it normally.
  667. 6148 return shell->HandlePositionedEvent(frame, aEvent, aEventStatus);
  668. 6149 }
  669. 6150
  670. 6151 return HandlePositionedEvent(frame, aEvent, aEventStatus);
  671. 6152 }
  672. 6153
  673. 6154 nsresult rv = NS_OK;
  674. 6155
  675. 6156 if (frame) {
  676. 6157 PushCurrentEventInfo(nsnull, nsnull);
  677. 6158
  678. 6159 // key and IME related events go to the focused frame in this DOM window.
  679. 6160 if (NS_IsEventTargetedAtFocusedContent(aEvent)) {
  680. 6161 mCurrentEventContent = nsnull;
  681. 6162
  682. 6163 nsCOMPtr<nsPIDOMWindow> window =
  683. 6164 do_QueryInterface(mDocument->GetWindow());
  684. 6165 nsCOMPtr<nsPIDOMWindow> focusedWindow;
  685. 6166 nsCOMPtr<nsIContent> eventTarget =
  686. 6167 nsFocusManager::GetFocusedDescendant(window, false,
  687. 6168 getter_AddRefs(focusedWindow));
  688. 6169
  689. 6160 if (NS_IsEventTargetedAtFocusedContent(aEvent)) {
  690. 6161 mCurrentEventContent = nsnull;
  691. 6162
  692. 6163 nsCOMPtr<nsPIDOMWindow> window =
  693. 6164 do_QueryInterface(mDocument->GetWindow());
  694. 6165 nsCOMPtr<nsPIDOMWindow> focusedWindow;
  695. 6166 nsCOMPtr<nsIContent> eventTarget =
  696. 6167 nsFocusManager::GetFocusedDescendant(window, false,
  697. 6168 getter_AddRefs(focusedWindow));
  698. 6169
  699. 6170 // otherwise, if there is no focused content or the focused content has
  700. 6171 // no frame, just use the root content. This ensures that key events
  701. 6172 // still get sent to the window properly if nothing is focused or if a
  702. 6173 // frame goes away while it is focused.
  703. 6174 if (!eventTarget || !eventTarget->GetPrimaryFrame()) {
  704. 6175 nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
  705. 6176 if (htmlDoc) {
  706. 6177 nsCOMPtr<nsIDOMHTMLElement> body;
  707. 6178 htmlDoc->GetBody(getter_AddRefs(body));
  708. 6179 eventTarget = do_QueryInterface(body);
  709. 6180 if (!eventTarget) {
  710. 6181 eventTarget = mDocument->GetRootElement();
  711. 6182 }
  712. 6183 } else {
  713. 6184 eventTarget = mDocument->GetRootElement();
  714. 6185 }
  715. 6186 }
  716. 6187
  717. 6188 if (aEvent->message == NS_KEY_DOWN) {
  718. 6189 NS_IF_RELEASE(gKeyDownTarget);
  719. 6190 NS_IF_ADDREF(gKeyDownTarget = eventTarget);
  720. 6191 }
  721. 6192 else if ((aEvent->message == NS_KEY_PRESS || aEvent->message == NS_KEY_UP) &&
  722. 6193 gKeyDownTarget) {
  723. 6194 // If a different element is now focused for the keypress/keyup event
  724. 6195 // than what was focused during the keydown event, check if the new
  725. 6196 // focused element is not in a chrome document any more, and if so,
  726. 6197 // retarget the event back at the keydown target. This prevents a
  727. 6198 // content area from grabbing the focus from chrome in-between key
  728. 6199 // events.
  729. 6200 if (eventTarget &&
  730. 6201 nsContentUtils::IsChromeDoc(gKeyDownTarget->GetCurrentDoc()) !=
  731. 6202 nsContentUtils::IsChromeDoc(eventTarget->GetCurrentDoc())) {
  732. 6203 eventTarget = gKeyDownTarget;
  733. 6204 }
  734. 6205
  735. 6206 if (aEvent->message == NS_KEY_UP) {
  736. 6207 NS_RELEASE(gKeyDownTarget);
  737. 6208 }
  738. 6209 }
  739. 6210
  740. 6211 mCurrentEventFrame = nsnull;
  741. 6212 nsIDocument* targetDoc = eventTarget ? eventTarget->OwnerDoc() : nsnull;
  742. 6213 if (targetDoc && targetDoc != mDocument) {
  743. 6214 PopCurrentEventInfo();
  744. 6215 nsCOMPtr<nsIPresShell> shell = targetDoc->GetShell();
  745. 6216 if (shell) {
  746. 6217 rv = static_cast<PresShell*>(shell.get())->
  747. 6218 HandleRetargetedEvent(aEvent, aEventStatus, eventTarget);
  748. 6219 }
  749. 6220 return rv;
  750. 6221 } else {
  751. 6222 mCurrentEventContent = eventTarget;
  752. 6223 }
  753. 6224
  754. 6225 if (!mCurrentEventContent || !GetCurrentEventFrame() ||
  755. 6226 InZombieDocument(mCurrentEventContent)) {
  756. 6227 rv = RetargetEventToParent(aEvent, aEventStatus);
  757. 6228 PopCurrentEventInfo();
  758. 6229 return rv;
  759. 6230 }
  760. 6231 } else {
  761. 6232 mCurrentEventFrame = frame;
  762. 6233 }
  763. 6234 if (GetCurrentEventFrame()) {
  764. 6235 rv = HandleEventInternal(aEvent, aEventStatus);
  765. 6236 }
  766. 6237
  767. 6238 #ifdef NS_DEBUG
  768. 6239 ShowEventTargetDebug();
  769. 6240 #endif
  770. 6241 PopCurrentEventInfo();
  771. 6242 } else {
  772. 6243 // Activation events need to be dispatched even if no frame was found, since
  773. 6244 // we don't want the focus to be out of sync.
  774. 6245
  775. 6246 if (!NS_EVENT_NEEDS_FRAME(aEvent)) {
  776. 6247 mCurrentEventFrame = nsnull;
  777. 6248 return HandleEventInternal(aEvent, aEventStatus);
  778. 6249 }
  779. 6250 else if (NS_IS_KEY_EVENT(aEvent)) {
  780. 6251 // Keypress events in new blank tabs should not be completely thrown away.
  781. 6252 // Retarget them -- the parent chrome shell might make use of them.
  782. 6253 return RetargetEventToParent(aEvent, aEventStatus);
  783. 6254 }
  784. 6255 }
  785. 6256
  786. 6257 return rv;
  787. 6258 }
  788.  
  789.  
  790. #0 nsEventDispatcher::CreateEvent (aPresContext=0x7ffd59908800, aEvent=0x7fff47ee20d0, aEventType=..., aDOMEvent=0x7fff47ee1ee0)
  791. at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventDispatcher.cpp:768
  792. #1 0x00007ffd706a5e19 in nsEventListenerManager::HandleEventInternal (this=0x7ffd5d914040, aPresContext=0x7ffd59908800, aEvent=0x7fff47ee20d0, aDOMEvent=
  793. 0x7fff47ee1ee0, aCurrentTarget=0x7ffd5d913ce0, aFlags=514, aEventStatus=0x7fff47ee1ee8, aPusher=0x7fff47ee1f10)
  794. at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventListenerManager.cpp:788
  795. #2 0x00007ffd706d457a in nsEventListenerManager::HandleEvent (this=0x7ffd5d914040, aPresContext=0x7ffd59908800, aEvent=0x7fff47ee20d0, aDOMEvent=
  796. 0x7fff47ee1ee0, aCurrentTarget=0x7ffd5d913ce0, aFlags=514, aEventStatus=0x7fff47ee1ee8, aPusher=0x7fff47ee1f10)
  797. at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventListenerManager.h:169
  798. #3 0x00007ffd706d4aaa in nsEventTargetChainItem::HandleEvent (this=0x7ffd5d51f0e0, aVisitor=..., aFlags=514, aMayHaveNewListenerManagers=false, aPusher=
  799. 0x7fff47ee1f10) at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventDispatcher.cpp:215
  800. #4 0x00007ffd706d50c5 in nsEventTargetChainItem::HandleEventTargetChain (this=0x7ffd5d51f070, aVisitor=..., aFlags=518, aCallback=0x7fff47ee2150,
  801. aMayHaveNewListenerManagers=false, aPusher=0x7fff47ee1f10) at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventDispatcher.cpp:370
  802. #5 0x00007ffd706d51f1 in nsEventTargetChainItem::HandleEventTargetChain (this=0x7ffd5d51f070, aVisitor=..., aFlags=6, aCallback=0x7fff47ee2150,
  803. aMayHaveNewListenerManagers=false, aPusher=0x7fff47ee1f10) at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventDispatcher.cpp:402
  804. #6 0x00007ffd706d62f2 in nsEventDispatcher::Dispatch (aTarget=0x7ffd594fc310, aPresContext=0x7ffd59908800, aEvent=0x7fff47ee20d0, aDOMEvent=0x0,
  805. aEventStatus=0x7fff47ee217c, aCallback=0x7fff47ee2150, aTargets=0x0)
  806. at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventDispatcher.cpp:689
  807. #7 0x00007ffd706b4011 in nsEventStateManager::DispatchMouseEvent (this=0x7ffd635aa080, aEvent=0x7fff47ee2ce0, aMessage=332, aTargetContent=0x7ffd594fc310,
  808. aRelatedContent=0x0) at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventStateManager.cpp:3872
  809. #8 0x00007ffd706b45bd in nsEventStateManager::NotifyMouseOut (this=0x7ffd635aa080, aEvent=0x7fff47ee2ce0, aMovingInto=0x0)
  810. at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventStateManager.cpp:3983
  811. #9 0x00007ffd706b44ad in nsEventStateManager::NotifyMouseOut (this=0x7ffd5d59da00, aEvent=0x7fff47ee2ce0, aMovingInto=0x0)
  812. at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventStateManager.cpp:3955
  813. #10 0x00007ffd706b4c6a in nsEventStateManager::GenerateMouseEnterExit (this=0x7ffd5d59da00, aEvent=0x7fff47ee2ce0)
  814. at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventStateManager.cpp:4105
  815. #11 0x00007ffd706abf47 in nsEventStateManager::PreHandleEvent (this=0x7ffd5d59da00, aPresContext=0x7ffd5cb0c800, aEvent=0x7fff47ee2ce0, aTargetFrame=
  816. 0x7ffd5d52bc38, aStatus=0x7fff47ee2c14) at /home/diogogmt/mozilla-central-diogogmt/content/events/src/nsEventStateManager.cpp:1155
  817. #12 0x00007ffd7021dcfc in PresShell::HandleEventInternal (this=0x7ffd5cb5a000, aEvent=0x7fff47ee2ce0, aStatus=0x7fff47ee2c14)
  818. at /home/diogogmt/mozilla-central-diogogmt/layout/base/nsPresShell.cpp:6633
  819. #13 0x00007ffd7021d4aa in PresShell::HandlePositionedEvent (this=0x7ffd5cb5a000, aTargetFrame=0x7ffd5d52bc38, aEvent=0x7fff47ee2ce0, aEventStatus=
  820. 0x7fff47ee2c14) at /home/diogogmt/mozilla-central-diogogmt/layout/base/nsPresShell.cpp:6321
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement