Bug 413268, clientX/clientY properties not working for tooltip popupshowing event, r=smaug,sr=neil

This commit is contained in:
enndeakin@sympatico.ca 2008-02-20 12:16:55 -08:00
parent d7bbbdcaf4
commit 289ce984ab
4 changed files with 74 additions and 32 deletions

View File

@ -61,6 +61,7 @@
#include "nsIInterfaceRequestorUtils.h"
#include "nsIBaseWindow.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDOMMouseEvent.h"
// See matching definitions in nsXULPopupManager.h
nsNavigationDirection DirectionFromKeyCode_lr_tb [6] = {
@ -316,10 +317,23 @@ nsXULPopupManager::SetTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup)
nsIDocument* doc = aPopup->GetCurrentDoc();
if (doc) {
nsIPresShell* presShell = doc->GetPrimaryShell();
if (presShell) {
if (presShell && presShell->GetPresContext()) {
nsPresContext* presContext = presShell->GetPresContext();
nsIFrame* rootFrame = presShell->GetRootFrame();
if (rootFrame && presContext) {
if ((event->eventStructType == NS_MOUSE_EVENT ||
event->eventStructType == NS_MOUSE_SCROLL_EVENT) &&
!(static_cast<nsGUIEvent *>(event))->widget) {
// no widget, so just use the client point if available
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent);
mouseEvent->GetClientX(&mCachedMousePoint.x);
mouseEvent->GetClientY(&mCachedMousePoint.y);
// convert to device pixels
PRInt32 adj = presContext->DeviceContext()->AppUnitsPerDevPixel();
mCachedMousePoint.x = nsPresContext::CSSPixelsToAppUnits(mCachedMousePoint.x) / adj;
mCachedMousePoint.y = nsPresContext::CSSPixelsToAppUnits(mCachedMousePoint.y) / adj;
}
else if (rootFrame) {
nsPoint pnt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(event, rootFrame);
mCachedMousePoint = nsPoint(presContext->AppUnitsToDevPixels(pnt.x),

View File

@ -62,6 +62,7 @@
#include "nsXULPopupManager.h"
#endif
#include "nsIRootBox.h"
#include "nsEventDispatcher.h"
nsXULTooltipListener* nsXULTooltipListener::mInstance = nsnull;
@ -69,8 +70,8 @@ nsXULTooltipListener* nsXULTooltipListener::mInstance = nsnull;
//// nsISupports
nsXULTooltipListener::nsXULTooltipListener()
: mMouseClientX(0)
, mMouseClientY(0)
: mMouseScreenX(0)
, mMouseScreenY(0)
#ifdef MOZ_XUL
, mIsSourceTree(PR_FALSE)
, mNeedTitletip(PR_FALSE)
@ -199,10 +200,11 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
PRInt32 newMouseX, newMouseY;
mouseEvent->GetScreenX(&newMouseX);
mouseEvent->GetScreenY(&newMouseY);
if (mMouseClientX == newMouseX && mMouseClientY == newMouseY)
if (mMouseScreenX == newMouseX && mMouseScreenY == newMouseY)
return NS_OK;
mMouseClientX = newMouseX;
mMouseClientY = newMouseY;
mMouseScreenX = newMouseX;
mMouseScreenY = newMouseY;
mCachedMouseEvent = aMouseEvent;
nsCOMPtr<nsIDOMEventTarget> eventTarget;
aMouseEvent->GetCurrentTarget(getter_AddRefs(eventTarget));
@ -510,7 +512,11 @@ nsXULTooltipListener::LaunchTooltip()
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (pm) {
pm->ShowPopupAtScreen(currentTooltip, mMouseClientX, mMouseClientY, PR_FALSE, nsnull);
pm->ShowPopupAtScreen(currentTooltip, mMouseScreenX, mMouseScreenY,
PR_FALSE, mCachedMouseEvent);
mCachedMouseEvent = nsnull;
// Clear the current tooltip if the popup was not opened successfully.
if (!pm->IsPopupOpen(currentTooltip))
mCurrentTooltip = nsnull;
@ -522,6 +528,8 @@ nsXULTooltipListener::LaunchTooltip()
nsresult
nsXULTooltipListener::HideTooltip()
{
mCachedMouseEvent = nsnull;
#ifdef MOZ_XUL
nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip);
if (currentTooltip) {

View File

@ -139,7 +139,13 @@ protected:
// a timer for showing the tooltip
nsCOMPtr<nsITimer> mTooltipTimer;
static void sTooltipCallback (nsITimer* aTimer, void* aListener);
PRInt32 mMouseClientX, mMouseClientY;
// screen coordinates of the last mousemove event, stored so that the
// tooltip can be opened at this location.
PRInt32 mMouseScreenX, mMouseScreenY;
// last cached mouse event
nsCOMPtr<nsIDOMEvent> mCachedMouseEvent;
// a timer for auto-hiding the tooltip after a certain delay
nsCOMPtr<nsITimer> mAutoHideTimer;

View File

@ -2,7 +2,7 @@
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window title="Tooltip Tests"
onfocus="runTests()"
onfocus="runTests()" onpopupshowing="checkCoords(event)"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
@ -28,21 +28,35 @@
var gOriginalWidth = -1;
var gOriginalHeight = -1;
var gButton = null;
function runTests()
{
startPopupTests(popupTests);
}
function checkCoords(event)
{
// all but one test open the tooltip at the button location offset by 6
// in each direction. Test 5 opens it at 4 in each direction.
var mod = (gTestIndex == 5) ? 4 : 6;
var rect = gButton.getBoundingClientRect();
is(event.clientX, Math.round(rect.left) + mod, "step " + (gTestIndex + 1) + " clientX");
is(event.clientY, Math.round(rect.top) + mod, "step " + (gTestIndex + 1) + " clientY");
ok(event.screenX > 0, "step " + (gTestIndex + 1) + " screenX");
ok(event.screenY > 0, "step " + (gTestIndex + 1) + " screenY");
}
var popupTests = [
{
testname: "hover tooltiptext attribute",
events: [ "popupshowing #tooltip", "popupshown #tooltip" ],
test: function() {
var button = document.getElementById("withtext");
synthesizeMouse(button, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 4, 4, { type: "mousemove" });
synthesizeMouse(button, 6, 6, { type: "mousemove" });
gButton = document.getElementById("withtext");
synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
}
},
{
@ -57,10 +71,10 @@ var popupTests = [
testname: "hover inherited tooltip",
events: [ "popupshowing #tooltip", "popupshown #tooltip" ],
test: function() {
var button = document.getElementById("without");
synthesizeMouse(button, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 4, 4, { type: "mousemove" });
synthesizeMouse(button, 6, 6, { type: "mousemove" });
gButton = document.getElementById("without");
synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
}
},
{
@ -69,10 +83,10 @@ var popupTests = [
"DOMMenuInactive #tooltip",
"popupshowing thetooltip", "popupshown thetooltip" ],
test: function() {
var button = document.getElementById("withtooltip");
synthesizeMouse(button, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 4, 4, { type: "mousemove" });
synthesizeMouse(button, 6, 6, { type: "mousemove" });
gButton = document.getElementById("withtooltip");
synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
},
result: function(testname) {
var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();
@ -99,8 +113,8 @@ var popupTests = [
events: [ "popuphiding thetooltip", "popuphidden thetooltip",
"command withtooltip", "DOMMenuInactive thetooltip" ],
test: function() {
var button = document.getElementById("withtooltip");
synthesizeMouse(button, 2, 2, { });
gButton = document.getElementById("withtooltip");
synthesizeMouse(gButton, 2, 2, { });
},
},
{
@ -110,10 +124,10 @@ var popupTests = [
var label = document.getElementById("label");
label.removeAttribute("value");
label.textContent = "This is a longer tooltip than before\nIt has multiple lines\nIt is testing tooltip sizing\n";
var button = document.getElementById("withtooltip");
synthesizeMouse(button, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 6, 6, { type: "mousemove" });
synthesizeMouse(button, 4, 4, { type: "mousemove" });
gButton = document.getElementById("withtooltip");
synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
},
result: function(testname) {
var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();
@ -153,10 +167,10 @@ var popupTests = [
test: function() {
var label = document.getElementById("label");
label.value = "This is a tooltip";
var button = document.getElementById("withtooltip");
synthesizeMouse(button, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 4, 4, { type: "mousemove" });
synthesizeMouse(button, 6, 6, { type: "mousemove" });
gButton = document.getElementById("withtooltip");
synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
},
result: function(testname) {
var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();