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 20:16:55 +00:00
Родитель 28b9310bc1
Коммит 5a9bde7ad8
4 изменённых файлов: 74 добавлений и 32 удалений

Просмотреть файл

@ -61,6 +61,7 @@
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsIBaseWindow.h" #include "nsIBaseWindow.h"
#include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeItem.h"
#include "nsIDOMMouseEvent.h"
// See matching definitions in nsXULPopupManager.h // See matching definitions in nsXULPopupManager.h
nsNavigationDirection DirectionFromKeyCode_lr_tb [6] = { nsNavigationDirection DirectionFromKeyCode_lr_tb [6] = {
@ -316,10 +317,23 @@ nsXULPopupManager::SetTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup)
nsIDocument* doc = aPopup->GetCurrentDoc(); nsIDocument* doc = aPopup->GetCurrentDoc();
if (doc) { if (doc) {
nsIPresShell* presShell = doc->GetPrimaryShell(); nsIPresShell* presShell = doc->GetPrimaryShell();
if (presShell) { if (presShell && presShell->GetPresContext()) {
nsPresContext* presContext = presShell->GetPresContext(); nsPresContext* presContext = presShell->GetPresContext();
nsIFrame* rootFrame = presShell->GetRootFrame(); 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 = nsPoint pnt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(event, rootFrame); nsLayoutUtils::GetEventCoordinatesRelativeTo(event, rootFrame);
mCachedMousePoint = nsPoint(presContext->AppUnitsToDevPixels(pnt.x), mCachedMousePoint = nsPoint(presContext->AppUnitsToDevPixels(pnt.x),

Просмотреть файл

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

Просмотреть файл

@ -139,7 +139,13 @@ protected:
// a timer for showing the tooltip // a timer for showing the tooltip
nsCOMPtr<nsITimer> mTooltipTimer; nsCOMPtr<nsITimer> mTooltipTimer;
static void sTooltipCallback (nsITimer* aTimer, void* aListener); 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 // a timer for auto-hiding the tooltip after a certain delay
nsCOMPtr<nsITimer> mAutoHideTimer; nsCOMPtr<nsITimer> mAutoHideTimer;

Просмотреть файл

@ -2,7 +2,7 @@
<?xml-stylesheet href="chrome://global/skin" type="text/css"?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window title="Tooltip Tests" <window title="Tooltip Tests"
onfocus="runTests()" onfocus="runTests()" onpopupshowing="checkCoords(event)"
xmlns:html="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
@ -28,21 +28,35 @@
var gOriginalWidth = -1; var gOriginalWidth = -1;
var gOriginalHeight = -1; var gOriginalHeight = -1;
var gButton = null;
function runTests() function runTests()
{ {
startPopupTests(popupTests); 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 = [ var popupTests = [
{ {
testname: "hover tooltiptext attribute", testname: "hover tooltiptext attribute",
events: [ "popupshowing #tooltip", "popupshown #tooltip" ], events: [ "popupshowing #tooltip", "popupshown #tooltip" ],
test: function() { test: function() {
var button = document.getElementById("withtext"); gButton = document.getElementById("withtext");
synthesizeMouse(button, 2, 2, { type: "mouseover" }); synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 4, 4, { type: "mousemove" }); synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
synthesizeMouse(button, 6, 6, { type: "mousemove" }); synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
} }
}, },
{ {
@ -57,10 +71,10 @@ var popupTests = [
testname: "hover inherited tooltip", testname: "hover inherited tooltip",
events: [ "popupshowing #tooltip", "popupshown #tooltip" ], events: [ "popupshowing #tooltip", "popupshown #tooltip" ],
test: function() { test: function() {
var button = document.getElementById("without"); gButton = document.getElementById("without");
synthesizeMouse(button, 2, 2, { type: "mouseover" }); synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 4, 4, { type: "mousemove" }); synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
synthesizeMouse(button, 6, 6, { type: "mousemove" }); synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
} }
}, },
{ {
@ -69,10 +83,10 @@ var popupTests = [
"DOMMenuInactive #tooltip", "DOMMenuInactive #tooltip",
"popupshowing thetooltip", "popupshown thetooltip" ], "popupshowing thetooltip", "popupshown thetooltip" ],
test: function() { test: function() {
var button = document.getElementById("withtooltip"); gButton = document.getElementById("withtooltip");
synthesizeMouse(button, 2, 2, { type: "mouseover" }); synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 4, 4, { type: "mousemove" }); synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
synthesizeMouse(button, 6, 6, { type: "mousemove" }); synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
}, },
result: function(testname) { result: function(testname) {
var buttonrect = document.getElementById("withtooltip").getBoundingClientRect(); var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();
@ -99,8 +113,8 @@ var popupTests = [
events: [ "popuphiding thetooltip", "popuphidden thetooltip", events: [ "popuphiding thetooltip", "popuphidden thetooltip",
"command withtooltip", "DOMMenuInactive thetooltip" ], "command withtooltip", "DOMMenuInactive thetooltip" ],
test: function() { test: function() {
var button = document.getElementById("withtooltip"); gButton = document.getElementById("withtooltip");
synthesizeMouse(button, 2, 2, { }); synthesizeMouse(gButton, 2, 2, { });
}, },
}, },
{ {
@ -110,10 +124,10 @@ var popupTests = [
var label = document.getElementById("label"); var label = document.getElementById("label");
label.removeAttribute("value"); label.removeAttribute("value");
label.textContent = "This is a longer tooltip than before\nIt has multiple lines\nIt is testing tooltip sizing\n"; label.textContent = "This is a longer tooltip than before\nIt has multiple lines\nIt is testing tooltip sizing\n";
var button = document.getElementById("withtooltip"); gButton = document.getElementById("withtooltip");
synthesizeMouse(button, 2, 2, { type: "mouseover" }); synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 6, 6, { type: "mousemove" }); synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
synthesizeMouse(button, 4, 4, { type: "mousemove" }); synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
}, },
result: function(testname) { result: function(testname) {
var buttonrect = document.getElementById("withtooltip").getBoundingClientRect(); var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();
@ -153,10 +167,10 @@ var popupTests = [
test: function() { test: function() {
var label = document.getElementById("label"); var label = document.getElementById("label");
label.value = "This is a tooltip"; label.value = "This is a tooltip";
var button = document.getElementById("withtooltip"); gButton = document.getElementById("withtooltip");
synthesizeMouse(button, 2, 2, { type: "mouseover" }); synthesizeMouse(gButton, 2, 2, { type: "mouseover" });
synthesizeMouse(button, 4, 4, { type: "mousemove" }); synthesizeMouse(gButton, 4, 4, { type: "mousemove" });
synthesizeMouse(button, 6, 6, { type: "mousemove" }); synthesizeMouse(gButton, 6, 6, { type: "mousemove" });
}, },
result: function(testname) { result: function(testname) {
var buttonrect = document.getElementById("withtooltip").getBoundingClientRect(); var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();