Bug 329385, r+sr=jst

This commit is contained in:
Olli.Pettay@helsinki.fi 2008-03-18 17:06:22 -07:00
parent 8d019da0ae
commit 160640b979
4 changed files with 61 additions and 7 deletions

View File

@ -194,6 +194,7 @@
#include "nsIPopupWindowManager.h"
#include "nsIPermissionManager.h"
#include "nsIDragService.h"
#ifdef MOZ_LOGGING
// so we can get logging even in release builds
@ -212,6 +213,8 @@ static PRInt32 gRefCnt = 0;
static PRInt32 gOpenPopupSpamCount = 0;
static PopupControlState gPopupControlState = openAbused;
static PRInt32 gRunningTimeoutDepth = 0;
static PRBool gMouseDown = PR_FALSE;
static PRBool gDragServiceDisabled = PR_FALSE;
#ifdef DEBUG
static PRUint32 gSerialCounter = 0;
@ -2181,6 +2184,20 @@ nsGlobalWindow::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
}
} else if (msg == NS_RESIZE_EVENT) {
mIsHandlingResizeEvent = PR_TRUE;
} else if (msg == NS_MOUSE_BUTTON_DOWN &&
NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
gMouseDown = PR_TRUE;
} else if (msg == NS_MOUSE_BUTTON_UP &&
NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
gMouseDown = PR_FALSE;
if (gDragServiceDisabled) {
nsCOMPtr<nsIDragService> ds =
do_GetService("@mozilla.org/widget/dragservice;1");
if (ds) {
gDragServiceDisabled = PR_FALSE;
ds->Unsuppress();
}
}
}
aVisitor.mParentTarget = mChromeEventHandler;
@ -3947,8 +3964,19 @@ nsGlobalWindow::CanMoveResizeWindows()
PRUint32 testResult;
rv = pm->TestPermission(uri, "moveresize", &testResult);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
return testResult == nsIPermissionManager::ALLOW_ACTION;
if (testResult == nsIPermissionManager::ALLOW_ACTION) {
if (gMouseDown && !gDragServiceDisabled) {
nsCOMPtr<nsIDragService> ds =
do_GetService("@mozilla.org/widget/dragservice;1");
if (ds) {
gDragServiceDisabled = PR_TRUE;
ds->Suppress();
}
}
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP

View File

@ -47,7 +47,7 @@ interface nsIDOMNode;
interface nsIDOMMouseEvent;
interface nsISelection;
[scriptable, uuid(E8CD74A6-8BB6-4D27-9C65-4ED1B4398F8C)]
[scriptable, uuid(034c44a4-604b-44a2-9205-676d5135f359)]
interface nsIDragService : nsISupports
{
const long DRAGDROP_ACTION_NONE = 0;
@ -134,6 +134,13 @@ interface nsIDragService : nsISupports
* Fire a drag event at the source of the drag
*/
void fireDragEventAtSource ( in unsigned long aMsg );
/**
* Increase/decrease dragging suppress level by one.
* If level is greater than one, dragging is disabled.
*/
void suppress();
void unsuppress();
};

View File

@ -79,7 +79,7 @@
nsBaseDragService::nsBaseDragService()
: mCanDrop(PR_FALSE), mDoingDrag(PR_FALSE), mHasImage(PR_FALSE),
mDragAction(DRAGDROP_ACTION_NONE), mTargetSize(0,0),
mImageX(0), mImageY(0), mScreenX(-1), mScreenY(-1)
mImageX(0), mImageY(0), mScreenX(-1), mScreenY(-1), mSuppressLevel(0)
{
}
@ -203,6 +203,7 @@ nsBaseDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
PRUint32 aActionType)
{
NS_ENSURE_TRUE(aDOMNode, NS_ERROR_INVALID_ARG);
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
// stash the document of the dom node
aDOMNode->GetOwnerDocument(getter_AddRefs(mSourceDocument));
@ -241,6 +242,7 @@ nsBaseDragService::InvokeDragSessionWithImage(nsIDOMNode* aDOMNode,
nsIDOMMouseEvent* aDragEvent)
{
NS_ENSURE_TRUE(aDragEvent, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
mSelection = nsnull;
mHasImage = PR_TRUE;
@ -262,6 +264,7 @@ nsBaseDragService::InvokeDragSessionWithSelection(nsISelection* aSelection,
{
NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aDragEvent, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
mSelection = aSelection;
mHasImage = PR_TRUE;
@ -288,7 +291,7 @@ nsBaseDragService::GetCurrentSession(nsIDragSession ** aSession)
// "this" also implements a drag session, so say we are one but only
// if there is currently a drag going on.
if (mDoingDrag) {
if (!mSuppressLevel && mDoingDrag) {
*aSession = this;
NS_ADDREF(*aSession); // addRef because we're a "getter"
}
@ -317,7 +320,7 @@ nsBaseDragService::EndDragSession(PRBool aDoneDrag)
return NS_ERROR_FAILURE;
}
if (aDoneDrag)
if (aDoneDrag && !mSuppressLevel)
FireDragEventAtSource(NS_DRAGDROP_END);
mDoingDrag = PR_FALSE;
@ -339,7 +342,7 @@ nsBaseDragService::EndDragSession(PRBool aDoneDrag)
NS_IMETHODIMP
nsBaseDragService::FireDragEventAtSource(PRUint32 aMsg)
{
if (mSourceNode) {
if (mSourceNode && !mSuppressLevel) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mSourceDocument);
if (doc) {
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
@ -578,3 +581,17 @@ nsBaseDragService::ConvertToUnscaledDevPixels(nsPresContext* aPresContext,
*aScreenY = nsPresContext::CSSPixelsToAppUnits(*aScreenY) / adj;
}
NS_IMETHODIMP
nsBaseDragService::Suppress()
{
EndDragSession(PR_FALSE);
++mSuppressLevel;
return NS_OK;
}
NS_IMETHODIMP
nsBaseDragService::Unsuppress()
{
--mSuppressLevel;
return NS_OK;
}

View File

@ -146,6 +146,8 @@ protected:
// supplied so the screen position is not known
PRInt32 mScreenX;
PRInt32 mScreenY;
PRUint32 mSuppressLevel;
};
#endif // nsBaseDragService_h__