Bug 385536: a tree inside a panel doesn't respond to clicks (make clientX/Y sane). r+sr=roc, a=blocking1.9+

This commit is contained in:
sharparrow1@yahoo.com 2007-08-03 17:31:42 -07:00
parent a47a2eb668
commit 74400dfa21

View File

@ -45,13 +45,11 @@
#include "nsIDOMNode.h"
#include "nsIContent.h"
#include "nsContentUtils.h"
#include "nsIWidget.h"
#include "nsIPresShell.h"
#include "nsIEventStateManager.h"
#include "nsIFrame.h"
#include "nsLayoutUtils.h"
#include "nsIScrollableFrame.h"
#include "nsIViewManager.h"
nsDOMUIEvent::nsDOMUIEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent ?
@ -154,89 +152,13 @@ nsPoint nsDOMUIEvent::GetClientPoint() {
return nsPoint(0, 0);
}
//My god, man, there *must* be a better way to do this.
nsCOMPtr<nsIWidget> docWidget;
nsIPresShell *presShell = mPresContext->GetPresShell();
if (presShell) {
nsIViewManager* vm = presShell->GetViewManager();
if (vm) {
vm->GetWidget(getter_AddRefs(docWidget));
}
}
nsPoint pt(0, 0);
nsIFrame* rootFrame = mPresContext->PresShell()->GetRootFrame();
if (rootFrame)
pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, rootFrame);
nsCOMPtr<nsIWidget> eventWidget = ((nsGUIEvent*)mEvent)->widget;
if (!eventWidget || !docWidget)
return mClientPoint;
nsPoint pt = mEvent->refPoint;
// BUG 296004 (see also BUG 242833)
//
// For document events we want to return a point relative to the local view manager,
// (docWidget) not to the generating widget (eventWidget). However, for global events
// we want to leave them relative to the generating widget.
//
// To determine which we are, we use the fact that currently for the latter case our
// docWidget and eventWidget won't be linked together in the widget hierarchy. That
// means that the coordinate space transform which follows wouldn't have worked
// anyway... actually what we want is for all users of this and refPoint to agree
// gracefully on what coordinate system to use, but that's a more involved change.
nsIWidget* eventParent = eventWidget;
for (;;) {
nsIWidget* t = eventParent->GetParent();
if (!t)
break;
eventParent = t;
}
nsIWidget* docParent = docWidget;
for (;;) {
nsIWidget* t = docParent->GetParent();
if (!t)
break;
docParent = t;
}
if (docParent != eventParent)
return pt;
while (eventWidget && docWidget != eventWidget) {
nsWindowType windowType;
eventWidget->GetWindowType(windowType);
if (windowType == eWindowType_popup)
break;
nsRect bounds;
eventWidget->GetBounds(bounds);
pt += bounds.TopLeft();
eventWidget = eventWidget->GetParent();
}
if (eventWidget != docWidget) {
// docWidget wasn't on the chain from the event widget to the root
// of the widget tree (or the nearest popup). OK, so now pt is
// relative to eventWidget; to get it relative to docWidget, we
// need to subtract docWidget's offset from eventWidget.
while (docWidget && docWidget != eventWidget) {
nsWindowType windowType;
docWidget->GetWindowType(windowType);
if (windowType == eWindowType_popup) {
// oh dear. the doc and the event were in different popups?
// That shouldn't happen.
NS_NOTREACHED("doc widget and event widget are in different popups. That's dumb.");
break;
}
nsRect bounds;
docWidget->GetBounds(bounds);
pt -= bounds.TopLeft();
docWidget = docWidget->GetParent();
}
}
return nsPoint(nsPresContext::AppUnitsToIntCSSPixels(mPresContext->DevPixelsToAppUnits(pt.x)),
nsPresContext::AppUnitsToIntCSSPixels(mPresContext->DevPixelsToAppUnits(pt.y)));
return nsPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
}
NS_IMETHODIMP