Bug 517737. Don't allow starting a drag if something is capturing the mouse. r=smaug(part of),enndeakin

--HG--
extra : rebase_source : 171cef43d1fef9337b49d6f3b9ca661c3e618437
This commit is contained in:
Timothy Nikkel 2010-02-02 20:07:08 -06:00
parent 9d1ebd2487
commit c63f549245
5 changed files with 41 additions and 2 deletions

View File

@ -1124,7 +1124,8 @@ nsNSElementTearoff::SetCapture(PRBool aRetargetToElement)
if (node)
return NS_OK;
nsIPresShell::SetCapturingContent(mContent, aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0);
nsIPresShell::SetCapturingContent(mContent, CAPTURE_PREVENTDRAG |
(aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0));
return NS_OK;
}

View File

@ -1891,6 +1891,12 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
}
}
// If non-native code is capturing the mouse don't start a drag.
if (nsIPresShell::IsMouseCapturePreventingDrag()) {
StopTrackingDragGesture();
return;
}
static PRInt32 pixelThresholdX = 0;
static PRInt32 pixelThresholdY = 0;

View File

@ -111,15 +111,19 @@ typedef PRUint32 nsFrameState;
#define CAPTURE_IGNOREALLOWED 1
// true if events should be targeted at the capturing content or its children
#define CAPTURE_RETARGETTOELEMENT 2
// true if the current capture wants drags to be prevented
#define CAPTURE_PREVENTDRAG 4
typedef struct CapturingContentInfo {
// capture should only be allowed during a mousedown event
PRPackedBool mAllowed;
PRPackedBool mRetargetToElement;
PRPackedBool mPreventDrag;
nsIContent* mContent;
CapturingContentInfo() :
mAllowed(PR_FALSE), mRetargetToElement(PR_FALSE), mContent(nsnull) { }
mAllowed(PR_FALSE), mRetargetToElement(PR_FALSE), mPreventDrag(PR_FALSE),
mContent(nsnull) { }
} CapturingContentInfo;
#define NS_IPRESSHELL_IID \
@ -958,6 +962,9 @@ public:
* descendants. That is, descendants of aContent receive mouse events as
* they normally would, but mouse events outside of aContent are retargeted
* to aContent.
*
* If CAPTURE_PREVENTDRAG is set then drags are prevented from starting while
* this capture is active.
*/
static void SetCapturingContent(nsIContent* aContent, PRUint8 aFlags);
@ -977,6 +984,15 @@ public:
gCaptureInfo.mAllowed = aAllowed;
}
/**
* Returns true if there is an active mouse capture that wants to prevent
* drags.
*/
static PRBool IsMouseCapturePreventingDrag()
{
return gCaptureInfo.mPreventDrag && gCaptureInfo.mContent;
}
protected:
// IMPORTANT: The ownership implicit in the following member variables
// has been explicitly checked. If you add any members to this class,

View File

@ -5819,6 +5819,7 @@ nsIPresShell::SetCapturingContent(nsIContent* aContent, PRUint8 aFlags)
NS_ADDREF(gCaptureInfo.mContent = aContent);
}
gCaptureInfo.mRetargetToElement = (aFlags & CAPTURE_RETARGETTOELEMENT) != 0;
gCaptureInfo.mPreventDrag = (aFlags & CAPTURE_PREVENTDRAG) != 0;
}
}

View File

@ -130,6 +130,14 @@ function runTests()
$("leftbox"), "mousemove", "setCapture only works on elements in documents");
synthesizeMouse(custom6, 2, 2, { type: "mouseup" });
// test that mousedown on an image with setCapture followed by a big enough
// mouse move does not start a drag (bug 517737)
var image = document.getElementById("image");
synthesizeMouse(image, 2, 2, { type: "mousedown" });
synthesizeMouseExpectEvent($("leftbox"), 2, 2, { type: "mousemove" },
image, "mousemove", "setCapture works on images");
synthesizeMouse(image, 2, 2, { type: "mouseup" });
var b = frames[0].document.getElementById("b");
runCaptureTest(b, selectionCallback);
@ -275,6 +283,13 @@ SimpleTest.waitForFocus(runTests);
</select>
</hbox>
<hbox>
<img id="image" xmlns="http://www.w3.org/1999/xhtml"
onmousedown="this.setCapture();" onmouseup="this.releaseCapture();"
ondragstart="ok(false, 'should not get a drag when a setCapture is active');"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC"/>
</hbox>
<body id="body" xmlns="http://www.w3.org/1999/xhtml">
<p id="display"/><div id="content" style="display: none"/><pre id="test"/>
</body>