mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 563329 - Add a preference to enable/disable click hold context menus [r=smaug]
This commit is contained in:
parent
f702826779
commit
ae3e280802
@ -770,7 +770,8 @@ nsEventStateManager::nsEventStateManager()
|
||||
mNormalLMouseEventInProcess(PR_FALSE),
|
||||
m_haveShutdown(PR_FALSE),
|
||||
mLastLineScrollConsumedX(PR_FALSE),
|
||||
mLastLineScrollConsumedY(PR_FALSE)
|
||||
mLastLineScrollConsumedY(PR_FALSE),
|
||||
mClickHoldContextMenu(PR_FALSE)
|
||||
{
|
||||
if (sESMInstanceCount == 0) {
|
||||
gUserInteractionTimerCallback = new nsUITimerCallback();
|
||||
@ -804,7 +805,6 @@ nsEventStateManager::Init()
|
||||
sLeftClickOnly =
|
||||
nsContentUtils::GetBoolPref("nglayout.events.dispatchLeftClickOnly",
|
||||
sLeftClickOnly);
|
||||
|
||||
sChromeAccessModifier =
|
||||
GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeChrome);
|
||||
sContentAccessModifier =
|
||||
@ -815,6 +815,7 @@ nsEventStateManager::Init()
|
||||
prefBranch->AddObserver("ui.key.generalAccessKey", this, PR_TRUE);
|
||||
prefBranch->AddObserver("ui.key.chromeAccess", this, PR_TRUE);
|
||||
prefBranch->AddObserver("ui.key.contentAccess", this, PR_TRUE);
|
||||
prefBranch->AddObserver("ui.click_hold_context_menus", this, PR_TRUE);
|
||||
#if 0
|
||||
prefBranch->AddObserver("mousewheel.withaltkey.action", this, PR_TRUE);
|
||||
prefBranch->AddObserver("mousewheel.withaltkey.numlines", this, PR_TRUE);
|
||||
@ -833,14 +834,16 @@ nsEventStateManager::Init()
|
||||
prefBranch->AddObserver("dom.popup_allowed_events", this, PR_TRUE);
|
||||
}
|
||||
|
||||
mClickHoldContextMenu =
|
||||
nsContentUtils::GetBoolPref("ui.click_hold_context_menus", PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsEventStateManager::~nsEventStateManager()
|
||||
{
|
||||
#if CLICK_HOLD_CONTEXT_MENUS
|
||||
KillClickHoldTimer();
|
||||
#endif
|
||||
if (mClickHoldContextMenu)
|
||||
KillClickHoldTimer();
|
||||
|
||||
--sESMInstanceCount;
|
||||
if(sESMInstanceCount == 0) {
|
||||
@ -882,6 +885,7 @@ nsEventStateManager::Shutdown()
|
||||
prefBranch->RemoveObserver("ui.key.generalAccessKey", this);
|
||||
prefBranch->RemoveObserver("ui.key.chromeAccess", this);
|
||||
prefBranch->RemoveObserver("ui.key.contentAccess", this);
|
||||
prefBranch->RemoveObserver("ui.click_hold_context_menus", this);
|
||||
#if 0
|
||||
prefBranch->RemoveObserver("mousewheel.withshiftkey.action", this);
|
||||
prefBranch->RemoveObserver("mousewheel.withshiftkey.numlines", this);
|
||||
@ -935,6 +939,9 @@ nsEventStateManager::Observe(nsISupports *aSubject,
|
||||
} else if (data.EqualsLiteral("ui.key.contentAccess")) {
|
||||
sContentAccessModifier =
|
||||
GetAccessModifierMaskFromPref(nsIDocShellTreeItem::typeContent);
|
||||
} else if (data.EqualsLiteral("ui.click_hold_context_menus")) {
|
||||
mClickHoldContextMenu =
|
||||
nsContentUtils::GetBoolPref("ui.click_hold_context_menus", PR_FALSE);
|
||||
#if 0
|
||||
} else if (data.EqualsLiteral("mousewheel.withaltkey.action")) {
|
||||
} else if (data.EqualsLiteral("mousewheel.withaltkey.numlines")) {
|
||||
@ -1063,7 +1070,7 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
switch (static_cast<nsMouseEvent*>(aEvent)->button) {
|
||||
case nsMouseEvent::eLeftButton:
|
||||
#ifndef XP_OS2
|
||||
BeginTrackingDragGesture ( aPresContext, (nsMouseEvent*)aEvent, aTargetFrame );
|
||||
BeginTrackingDragGesture(aPresContext, (nsMouseEvent*)aEvent, aTargetFrame);
|
||||
#endif
|
||||
mLClickCount = ((nsMouseEvent*)aEvent)->clickCount;
|
||||
SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
||||
@ -1075,7 +1082,7 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
break;
|
||||
case nsMouseEvent::eRightButton:
|
||||
#ifdef XP_OS2
|
||||
BeginTrackingDragGesture ( aPresContext, (nsMouseEvent*)aEvent, aTargetFrame );
|
||||
BeginTrackingDragGesture(aPresContext, (nsMouseEvent*)aEvent, aTargetFrame);
|
||||
#endif
|
||||
mRClickCount = ((nsMouseEvent*)aEvent)->clickCount;
|
||||
SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
||||
@ -1085,20 +1092,20 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
case NS_MOUSE_BUTTON_UP:
|
||||
switch (static_cast<nsMouseEvent*>(aEvent)->button) {
|
||||
case nsMouseEvent::eLeftButton:
|
||||
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
||||
KillClickHoldTimer();
|
||||
#endif
|
||||
if (mClickHoldContextMenu) {
|
||||
KillClickHoldTimer();
|
||||
}
|
||||
#ifndef XP_OS2
|
||||
StopTrackingDragGesture();
|
||||
StopTrackingDragGesture();
|
||||
#endif
|
||||
mNormalLMouseEventInProcess = PR_FALSE;
|
||||
case nsMouseEvent::eRightButton:
|
||||
mNormalLMouseEventInProcess = PR_FALSE;
|
||||
case nsMouseEvent::eRightButton:
|
||||
#ifdef XP_OS2
|
||||
StopTrackingDragGesture();
|
||||
StopTrackingDragGesture();
|
||||
#endif
|
||||
case nsMouseEvent::eMiddleButton:
|
||||
SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
||||
break;
|
||||
case nsMouseEvent::eMiddleButton:
|
||||
SetClickCount(aPresContext, (nsMouseEvent*)aEvent, aStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_MOUSE_EXIT:
|
||||
@ -1132,13 +1139,13 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
UpdateCursor(aPresContext, aEvent, mCurrentTarget, aStatus);
|
||||
GenerateMouseEnterExit((nsGUIEvent*)aEvent);
|
||||
break;
|
||||
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
||||
case NS_DRAGDROP_GESTURE:
|
||||
// an external drag gesture event came in, not generated internally
|
||||
// by Gecko. Make sure we get rid of the click-hold timer.
|
||||
KillClickHoldTimer();
|
||||
if (mClickHoldContextMenu) {
|
||||
// an external drag gesture event came in, not generated internally
|
||||
// by Gecko. Make sure we get rid of the click-hold timer.
|
||||
KillClickHoldTimer();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case NS_DRAGDROP_OVER:
|
||||
// NS_DRAGDROP_DROP is fired before NS_DRAGDROP_DRAGDROP so send
|
||||
// the enter/exit events before NS_DRAGDROP_DROP.
|
||||
@ -1585,9 +1592,6 @@ nsEventStateManager::HandleAccessKey(nsPresContext* aPresContext,
|
||||
}// end of HandleAccessKey
|
||||
|
||||
|
||||
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
||||
|
||||
|
||||
//
|
||||
// CreateClickHoldTimer
|
||||
//
|
||||
@ -1623,10 +1627,13 @@ nsEventStateManager::CreateClickHoldTimer(nsPresContext* inPresContext,
|
||||
}
|
||||
|
||||
mClickHoldTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if ( mClickHoldTimer )
|
||||
if (mClickHoldTimer) {
|
||||
PRInt32 clickHoldDelay =
|
||||
nsContentUtils::GetIntPref("ui.click_hold_context_menus.delay", 500);
|
||||
mClickHoldTimer->InitWithFuncCallback(sClickHoldCallback, this,
|
||||
kClickHoldDelay,
|
||||
clickHoldDelay,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
} // CreateClickHoldTimer
|
||||
|
||||
|
||||
@ -1654,7 +1661,7 @@ void
|
||||
nsEventStateManager::sClickHoldCallback(nsITimer *aTimer, void* aESM)
|
||||
{
|
||||
nsEventStateManager* self = static_cast<nsEventStateManager*>(aESM);
|
||||
if ( self )
|
||||
if (self)
|
||||
self->FireContextClick();
|
||||
|
||||
// NOTE: |aTimer| and |self->mAutoHideTimer| are invalid after calling ClosePopup();
|
||||
@ -1679,7 +1686,7 @@ nsEventStateManager::sClickHoldCallback(nsITimer *aTimer, void* aESM)
|
||||
void
|
||||
nsEventStateManager::FireContextClick()
|
||||
{
|
||||
if ( !mGestureDownContent )
|
||||
if (!mGestureDownContent)
|
||||
return;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
@ -1786,7 +1793,7 @@ nsEventStateManager::FireContextClick()
|
||||
}
|
||||
|
||||
// now check if the event has been handled. If so, stop tracking a drag
|
||||
if ( status == nsEventStatus_eConsumeNoDefault ) {
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
StopTrackingDragGesture();
|
||||
}
|
||||
|
||||
@ -1794,8 +1801,6 @@ nsEventStateManager::FireContextClick()
|
||||
|
||||
} // FireContextClick
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// BeginTrackingDragGesture
|
||||
@ -1803,7 +1808,7 @@ nsEventStateManager::FireContextClick()
|
||||
// Record that the mouse has gone down and that we should move to TRACKING state
|
||||
// of d&d gesture tracker.
|
||||
//
|
||||
// We also use this to track click-hold context menus on mac. When the mouse goes down,
|
||||
// We also use this to track click-hold context menus. When the mouse goes down,
|
||||
// fire off a short timer. If the timer goes off and we have yet to fire the
|
||||
// drag gesture (ie, the mouse hasn't moved a certain distance), then we can
|
||||
// assume the user wants a click-hold, so fire a context-click event. We only
|
||||
@ -1814,9 +1819,12 @@ nsEventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext,
|
||||
nsMouseEvent* inDownEvent,
|
||||
nsIFrame* inDownFrame)
|
||||
{
|
||||
if (!inDownEvent->widget)
|
||||
return;
|
||||
|
||||
// Note that |inDownEvent| could be either a mouse down event or a
|
||||
// synthesized mouse move event.
|
||||
mGestureDownPoint = inDownEvent->refPoint +
|
||||
mGestureDownPoint = inDownEvent->refPoint +
|
||||
inDownEvent->widget->WidgetToScreenOffset();
|
||||
|
||||
inDownFrame->GetContentForEvent(aPresContext, inDownEvent,
|
||||
@ -1828,11 +1836,10 @@ nsEventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext,
|
||||
mGestureDownAlt = inDownEvent->isAlt;
|
||||
mGestureDownMeta = inDownEvent->isMeta;
|
||||
|
||||
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
||||
// fire off a timer to track click-hold
|
||||
if (nsContentUtils::GetBoolPref("ui.click_hold_context_menus", PR_TRUE))
|
||||
CreateClickHoldTimer ( aPresContext, inDownFrame, inDownEvent );
|
||||
#endif
|
||||
if (mClickHoldContextMenu) {
|
||||
// fire off a timer to track click-hold
|
||||
CreateClickHoldTimer(aPresContext, inDownFrame, inDownEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1885,7 +1892,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
nsMouseEvent *aEvent)
|
||||
{
|
||||
NS_ASSERTION(aPresContext, "This shouldn't happen.");
|
||||
if ( IsTrackingDragGesture() ) {
|
||||
if (IsTrackingDragGesture()) {
|
||||
mCurrentTarget = mGestureDownFrameOwner->GetPrimaryFrame();
|
||||
|
||||
if (!mCurrentTarget) {
|
||||
@ -1927,11 +1934,11 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
nsIntPoint pt = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset();
|
||||
if (PR_ABS(pt.x - mGestureDownPoint.x) > pixelThresholdX ||
|
||||
PR_ABS(pt.y - mGestureDownPoint.y) > pixelThresholdY) {
|
||||
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
||||
// stop the click-hold before we fire off the drag gesture, in case
|
||||
// it takes a long time
|
||||
KillClickHoldTimer();
|
||||
#endif
|
||||
if (mClickHoldContextMenu) {
|
||||
// stop the click-hold before we fire off the drag gesture, in case
|
||||
// it takes a long time
|
||||
KillClickHoldTimer();
|
||||
}
|
||||
|
||||
nsRefPtr<nsDOMDataTransfer> dataTransfer = new nsDOMDataTransfer();
|
||||
if (!dataTransfer)
|
||||
@ -3663,7 +3670,7 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(targetContent));
|
||||
|
||||
if ( mLastDragOverFrame ) {
|
||||
if (mLastDragOverFrame) {
|
||||
//The frame has changed but the content may not have. Check before dispatching to content
|
||||
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
|
||||
|
||||
@ -3684,7 +3691,7 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
||||
case NS_DRAGDROP_EXIT:
|
||||
{
|
||||
//This is actually the window mouse exit event.
|
||||
if ( mLastDragOverFrame ) {
|
||||
if (mLastDragOverFrame) {
|
||||
nsCOMPtr<nsIContent> lastContent;
|
||||
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
|
||||
|
||||
|
@ -62,14 +62,6 @@ class nsIDocShellTreeItem;
|
||||
class imgIContainer;
|
||||
class nsDOMDataTransfer;
|
||||
|
||||
// mac uses click-hold context menus, a holdover from 4.x
|
||||
// touch screens (like maemo) could use this also,
|
||||
// perhaps we should move to NS_TOUCHSCREEN
|
||||
#if defined(XP_MACOSX) || defined(MOZ_PLATFORM_MAEMO)
|
||||
#define CLICK_HOLD_CONTEXT_MENUS 1
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Event listener manager
|
||||
*/
|
||||
@ -399,19 +391,16 @@ protected:
|
||||
PRPackedBool mLastLineScrollConsumedX;
|
||||
PRPackedBool mLastLineScrollConsumedY;
|
||||
|
||||
#ifdef CLICK_HOLD_CONTEXT_MENUS
|
||||
enum { kClickHoldDelay = 500 } ; // 500ms == 1/2 second
|
||||
static PRInt32 sUserInputEventDepth;
|
||||
|
||||
// Functions used for click hold context menus
|
||||
PRBool mClickHoldContextMenu;
|
||||
nsCOMPtr<nsITimer> mClickHoldTimer;
|
||||
void CreateClickHoldTimer ( nsPresContext* aPresContext, nsIFrame* inDownFrame,
|
||||
nsGUIEvent* inMouseDownEvent ) ;
|
||||
void KillClickHoldTimer ( ) ;
|
||||
void FireContextClick ( ) ;
|
||||
static void sClickHoldCallback ( nsITimer* aTimer, void* aESM ) ;
|
||||
|
||||
nsCOMPtr<nsITimer> mClickHoldTimer;
|
||||
#endif
|
||||
|
||||
static PRInt32 sUserInputEventDepth;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,6 +88,7 @@ _TEST_FILES = \
|
||||
test_bug547996-1.html \
|
||||
test_bug547996-2.xhtml \
|
||||
test_bug556493.html \
|
||||
test_bug563329.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
106
content/events/test/test_bug563329.html
Normal file
106
content/events/test/test_bug563329.html
Normal file
@ -0,0 +1,106 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=563329
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 563329</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=563329">Mozilla Bug 563329</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
/** Test for Bug 563329 **/
|
||||
/* ui.click_hold_context_menus preference */
|
||||
|
||||
var target = null;
|
||||
var tests = getTests();
|
||||
var currentTest = null;
|
||||
|
||||
function getTests() {
|
||||
let tests = [
|
||||
{ "func": function() { setTimeout(doCheckContextMenu, 100)}, "message": "Context menu should has fired"},
|
||||
{ "func": function() { setTimeout(doCheckDuration, 100)}, "message": "Context menu should has fired with delay"},
|
||||
{ "func": function() { setTimeout(finishTest, 100)}, "message": "" }
|
||||
];
|
||||
|
||||
let i = 0;
|
||||
while (i < tests.length)
|
||||
yield tests[i++];
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
// Enable context menus
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
prefs.setBoolPref("ui.click_hold_context_menus", true);
|
||||
|
||||
target = document.getElementById("testTarget");
|
||||
|
||||
document.documentElement.addEventListener("contextmenu", function() {
|
||||
SimpleTest.ok(true, currentTest.message);
|
||||
synthesizeMouse(target, 0, 0, {type: "mouseup"});
|
||||
SimpleTest.executeSoon(function() {
|
||||
currentTest = tests.next();
|
||||
currentTest.func();
|
||||
});
|
||||
}, false);
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
currentTest = tests.next();
|
||||
currentTest.func();
|
||||
});
|
||||
}
|
||||
|
||||
function doCheckContextMenu() {
|
||||
synthesizeMouse(target, 0, 0, {type: "mousedown"});
|
||||
}
|
||||
|
||||
function doCheckDuration() {
|
||||
var duration = 50;
|
||||
|
||||
// Change click hold delay
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
prefs.setIntPref("ui.click_hold_context_menus.delay", duration);
|
||||
|
||||
synthesizeMouse(target, 0, 0, {type: "mousedown"});
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
synthesizeKey("VK_ESCAPE", {}, window);
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
try {
|
||||
prefs.clearUserPref("ui.click_hold_context_menus");
|
||||
}
|
||||
catch(e) {}
|
||||
|
||||
try {
|
||||
prefs.clearUserPref("ui.click_hold_context_menus.delay");
|
||||
}
|
||||
catch(e) {}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<span id="testTarget" style="border: 1px solid black;">testTarget</span>
|
||||
</body>
|
||||
</html>
|
@ -96,6 +96,7 @@ pref("browser.sessionhistory.max_total_viewers", -1);
|
||||
|
||||
pref("ui.use_native_colors", true);
|
||||
pref("ui.use_native_popup_windows", false);
|
||||
pref("ui.click_hold_context_menus", false);
|
||||
pref("browser.display.use_document_fonts", 1); // 0 = never, 1 = quick, 2 = always
|
||||
pref("browser.display.use_document_colors", true);
|
||||
pref("browser.display.use_system_colors", false);
|
||||
@ -1726,7 +1727,6 @@ pref("ui.trackpoint_hack.enabled", -1);
|
||||
// Mac specific preference defaults
|
||||
pref("browser.drag_out_of_frame_style", 1);
|
||||
pref("ui.key.saveLink.shift", false); // true = shift, false = meta
|
||||
pref("ui.click_hold_context_menus", false);
|
||||
|
||||
// default fonts (in UTF8 and using canonical names)
|
||||
// to determine canonical font names, use a debug build and
|
||||
|
Loading…
Reference in New Issue
Block a user