Bug 786120 - Implement mousewheel.*.action.override_x. r=smaug

This commit is contained in:
Masatoshi Kimura 2012-12-08 13:08:19 +09:00
parent 2a936cec1d
commit 1e56bc30a5
4 changed files with 215 additions and 20 deletions

View File

@ -5457,13 +5457,25 @@ nsEventStateManager::WheelPrefs::Init(
nsAutoCString prefNameAction(basePrefName);
prefNameAction.AppendLiteral("action");
mActions[aIndex] =
static_cast<Action>(Preferences::GetInt(prefNameAction.get(),
ACTION_SCROLL));
if (mActions[aIndex] < ACTION_NONE || mActions[aIndex] > ACTION_LAST) {
int32_t action = Preferences::GetInt(prefNameAction.get(), ACTION_SCROLL);
if (action < ACTION_NONE || action > ACTION_LAST) {
NS_WARNING("Unsupported action pref value, replaced with 'Scroll'.");
mActions[aIndex] = ACTION_SCROLL;
action = ACTION_SCROLL;
}
mActions[aIndex] = static_cast<Action>(action);
// Compute action values overridden by .override_x pref.
// At present, override is possible only for the x-direction
// because this pref is introduced mainly for tilt wheels.
prefNameAction.AppendLiteral(".override_x");
int32_t actionOverrideX = Preferences::GetInt(prefNameAction.get(), -1);
if (actionOverrideX < -1 || actionOverrideX > ACTION_LAST) {
NS_WARNING("Unsupported action override pref value, didn't override.");
actionOverrideX = -1;
}
mOverriddenActionsX[aIndex] = (actionOverrideX == -1)
? static_cast<Action>(action)
: static_cast<Action>(actionOverrideX);
}
void
@ -5524,21 +5536,25 @@ nsEventStateManager::WheelPrefs::ComputeActionFor(widget::WheelEvent* aEvent)
Index index = GetIndexFor(aEvent);
Init(index);
if (mActions[index] == ACTION_NONE || mActions[index] == ACTION_SCROLL) {
return mActions[index];
bool deltaXPreferred =
(std::abs(aEvent->deltaX) > std::abs(aEvent->deltaY) &&
std::abs(aEvent->deltaX) > std::abs(aEvent->deltaZ));
Action* actions = deltaXPreferred ? mOverriddenActionsX : mActions;
if (actions[index] == ACTION_NONE || actions[index] == ACTION_SCROLL) {
return actions[index];
}
// Momentum events shouldn't run special actions.
if (aEvent->isMomentum) {
// Use the default action. Note that user might kill the wheel scrolling.
Init(INDEX_DEFAULT);
return (mActions[INDEX_DEFAULT] == ACTION_SCROLL) ? ACTION_SCROLL :
ACTION_NONE;
return (actions[INDEX_DEFAULT] == ACTION_SCROLL) ? ACTION_SCROLL :
ACTION_NONE;
}
// If this event doesn't cause NS_MOUSE_SCROLL event or the direction is
// oblique, history and zoom shouldn't be executed.
return !aEvent->GetPreferredIntDelta() ? ACTION_NONE : mActions[index];
return !aEvent->GetPreferredIntDelta() ? ACTION_NONE : actions[index];
}
bool

View File

@ -350,7 +350,7 @@ protected:
/**
* Computes the default action for the aEvent with the prefs.
*/
enum Action
enum Action MOZ_ENUM_TYPE(uint8_t)
{
ACTION_NONE = 0,
ACTION_SCROLL,
@ -428,6 +428,12 @@ protected:
double mMultiplierY[COUNT_OF_MULTIPLIERS];
double mMultiplierZ[COUNT_OF_MULTIPLIERS];
Action mActions[COUNT_OF_MULTIPLIERS];
/**
* action values overridden by .override_x pref.
* If an .override_x value is -1, same as the
* corresponding mActions value.
*/
Action mOverriddenActionsX[COUNT_OF_MULTIPLIERS];
static WheelPrefs* sInstance;
};

View File

@ -1531,6 +1531,166 @@ function doTestWholeScroll(aCallback)
doIt();
}
function doTestActionOverride(aCallback)
{
const kNoScroll = 0x00;
const kScrollUp = 0x01;
const kScrollDown = 0x02;
const kScrollLeft = 0x04;
const kScrollRight = 0x08;
const kTests = [
{ action: 1, override_x: -1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 1, override_x: 0,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 1, override_x: 1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 0, override_x: -1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
{ action: 0, override_x: 0,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
{ action: 0, override_x: 1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
{ action: 1, override_x: -1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 0.5,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 1, override_x: 0,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 0.5,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
{ action: 1, override_x: 1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 0.5,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 0, override_x: -1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 0.5,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
{ action: 0, override_x: 0,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 0.5,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
{ action: 0, override_x: 1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 0.5,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 1, override_x: -1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 0.5, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 1, override_x: 0,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 0.5, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 1, override_x: 1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 0.5, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kScrollDown | kScrollRight
},
{ action: 0, override_x: -1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 0.5, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
{ action: 0, override_x: 0,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 0.5, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
{ action: 0, override_x: 1,
event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 0.5, deltaY: 1.0,
lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
expected: kNoScroll
},
];
var index = 0;
function doIt()
{
const kTest = kTests[index];
description = "doTestActionOverride(action=" + kTest.action + ", " +
"override_x=" + kTest.override_x + ", " +
"deltaX=" + kTest.event.deltaX + ", " +
"deltaY=" + kTest.event.deltaY + "): ";
SpecialPowers.setIntPref("mousewheel.default.action", kTest.action);
SpecialPowers.setIntPref("mousewheel.default.action.override_x", kTest.override_x);
gScrollableElement.scrollTop = 1000;
gScrollableElement.scrollLeft = 1000;
synthesizeWheel(gScrollableElement, 10, 10, kTest.event);
hitEventLoop(function () {
if (kTest.expected & kScrollUp) {
ok(gScrollableElement.scrollTop < 1000, description + "not scrolled up, got " + gScrollableElement.scrollTop);
} else if (kTest.expected & kScrollDown) {
ok(gScrollableElement.scrollTop > 1000, description + "not scrolled down, got " + gScrollableElement.scrollTop);
} else {
is(gScrollableElement.scrollTop, 1000, description + "scrolled vertical");
}
if (kTest.expected & kScrollLeft) {
ok(gScrollableElement.scrollLeft < 1000, description + "not scrolled to left, got " + gScrollableElement.scrollLeft);
} else if (kTest.expected & kScrollRight) {
ok(gScrollableElement.scrollLeft > 1000, description + "not scrolled to right, got " + gScrollableElement.scrollLeft);
} else {
is(gScrollableElement.scrollLeft, 1000, description + "scrolled horizontal");
}
if (++index == kTests.length) {
SpecialPowers.setIntPref("mousewheel.default.action", 1);
SpecialPowers.clearUserPref("mousewheel.default.action.override_x");
SimpleTest.executeSoon(aCallback);
} else {
doIt();
}
}, 20);
}
doIt();
}
function runTests()
{
SpecialPowers.setBoolPref("general.smoothScroll", false);
@ -1567,19 +1727,21 @@ function runTests()
function doTest() {
setDeltaMultiplierSettings(kSettings[index]);
doTestScroll(kSettings[index], function () {
doTestZoom(kSettings[index], function() {
if (++index == kSettings.length) {
setDeltaMultiplierSettings(kSettings[0]);
doTestZoomedScroll(function() {
doTestWholeScroll(function() {
doTestZoom(kSettings[index], function() {
if (++index == kSettings.length) {
setDeltaMultiplierSettings(kSettings[0]);
doTestZoomedScroll(function() {
doTestWholeScroll(function() {
doTestActionOverride(function() {
finishTests();
});
});
} else {
doTest();
}
});
});
} else {
doTest();
}
});
});
}
doTest();
}

View File

@ -1445,6 +1445,17 @@ pref("mousewheel.with_meta.action", 1); // command key on Mac
pref("mousewheel.with_shift.action", 1);
pref("mousewheel.with_win.action", 1);
// mousewheel.*.action.override_x will override the action
// when the mouse wheel is rotated along the x direction.
// -1: Don't override the action.
// 0 to 3: Override the action with the specified value.
pref("mousewheel.default.action.override_x", -1);
pref("mousewheel.with_alt.action.override_x", -1);
pref("mousewheel.with_control.action.override_x", -1);
pref("mousewheel.with_meta.action.override_x", -1); // command key on Mac
pref("mousewheel.with_shift.action.override_x", -1);
pref("mousewheel.with_win.action.override_x", -1);
// mousewheel.*.delta_multiplier_* can specify the value muliplied by the delta
// value. The values will be used after divided by 100. I.e., 100 means 1.0,
// -100 means -1.0. If the values were negative, the direction would be