--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3384,39 +3384,46 @@ EventStateManager::PostHandleEvent(nsPre
// When APZ is enabled, the actual scroll animation might be handled by
// the compositor.
WheelPrefs::Action action =
wheelEvent->mFlags.mHandledByAPZ ?
WheelPrefs::ACTION_NONE :
WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
- // Make the wheel event a horizontal scroll event. I.e., deltaY values
- // are set to deltaX and deltaY and deltaZ values are set to 0.
- // When AutoWheelDeltaAdjuster instance is destroyed, the delta values
- // are restored and make overflow deltaX becomes 0.
- AutoWheelDeltaAdjuster adjuster(*wheelEvent);
+ WheelDeltaAdjustmentStrategy strategy =
+ GetWheelDeltaAdjustmentStrategy(*wheelEvent);
+ // Adjust the delta values of the wheel event if the current default
+ // action is to horizontalize scrolling. I.e., deltaY values are set to
+ // deltaX and deltaY and deltaZ values are set to 0.
+ // If horizontalized, the delta values will be restored and its overflow
+ // deltaX will become 0 when the WheelDeltaHorizontalizer instance is
+ // being destroyed.
+ WheelDeltaHorizontalizer horizontalizer(*wheelEvent);
+ if (WheelDeltaAdjustmentStrategy::eHorizontalize == strategy) {
+ horizontalizer.Horizontalize();
+ }
// Check if the frame to scroll before checking the default action
// because if the scroll target is a plugin, the default action should be
// chosen by the plugin rather than by our prefs.
nsIFrame* frameToScroll =
ComputeScrollTarget(mCurrentTarget, wheelEvent,
COMPUTE_DEFAULT_ACTION_TARGET);
nsPluginFrame* pluginFrame = do_QueryFrame(frameToScroll);
if (pluginFrame) {
MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction());
// Plugins should receive original values instead of adjusted values.
- adjuster.CancelAdjustment();
+ horizontalizer.CancelHorizontalization();
action = WheelPrefs::ACTION_SEND_TO_PLUGIN;
}
switch (action) {
case WheelPrefs::ACTION_SCROLL:
- case WheelPrefs::ACTION_HORIZONTAL_SCROLL: {
+ case WheelPrefs::ACTION_HORIZONTALIZED_SCROLL: {
// For scrolling of default action, we should honor the mouse wheel
// transaction.
ScrollbarsForWheel::PrepareToScrollText(this, mCurrentTarget, wheelEvent);
if (aEvent->mMessage != eWheel ||
(!wheelEvent->mDeltaX && !wheelEvent->mDeltaY)) {
break;
@@ -5926,45 +5933,45 @@ EventStateManager::WheelPrefs::Init(Even
NS_WARNING("Unsupported action pref value, replaced with '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.
- // Note that ACTION_HORIZONTAL_SCROLL isn't a valid value for this pref
+ // Note that ACTION_HORIZONTALIZED_SCROLL isn't a valid value for this pref
// because it affects only to deltaY.
prefNameAction.AppendLiteral(".override_x");
int32_t actionOverrideX = Preferences::GetInt(prefNameAction.get(), -1);
if (actionOverrideX < -1 || actionOverrideX > int32_t(ACTION_LAST) ||
- actionOverrideX == ACTION_HORIZONTAL_SCROLL) {
+ actionOverrideX == ACTION_HORIZONTALIZED_SCROLL) {
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
EventStateManager::WheelPrefs::GetMultiplierForDeltaXAndY(
const WidgetWheelEvent* aEvent,
Index aIndex,
double* aMultiplierForDeltaX,
double* aMultiplierForDeltaY)
{
- // If the event should be treated as horizontal wheel operation, deltaY
- // should be multiplied by mMultiplierY, however, it might be moved to
- // deltaX for handling default action. In such case, we need to treat
- // mMultiplierX and mMultiplierY as swapped.
*aMultiplierForDeltaX = mMultiplierX[aIndex];
*aMultiplierForDeltaY = mMultiplierY[aIndex];
- if (aEvent->mDeltaValuesAdjustedForDefaultHandler &&
- ComputeActionFor(aEvent) == ACTION_HORIZONTAL_SCROLL) {
+ // If the event has been horizontalized(I.e. treated as a horizontal wheel
+ // scroll for a vertical wheel scroll), then we should swap mMultiplierX and
+ // mMultiplierY. By doing this, multipliers will still apply to the delta
+ // values they origianlly corresponded to.
+ if (aEvent->mDeltaValuesHorizontalizedForDefaultHandler &&
+ ComputeActionFor(aEvent) == ACTION_HORIZONTALIZED_SCROLL) {
std::swap(*aMultiplierForDeltaX, *aMultiplierForDeltaY);
}
}
void
EventStateManager::WheelPrefs::ApplyUserPrefsToDelta(WidgetWheelEvent* aEvent)
{
if (aEvent->mCustomizedByUserPrefs) {
@@ -6028,26 +6035,26 @@ EventStateManager::WheelPrefs::ComputeAc
Init(index);
bool deltaXPreferred =
(Abs(aEvent->mDeltaX) > Abs(aEvent->mDeltaY) &&
Abs(aEvent->mDeltaX) > Abs(aEvent->mDeltaZ));
Action* actions = deltaXPreferred ? mOverriddenActionsX : mActions;
if (actions[index] == ACTION_NONE ||
actions[index] == ACTION_SCROLL ||
- actions[index] == ACTION_HORIZONTAL_SCROLL) {
+ actions[index] == ACTION_HORIZONTALIZED_SCROLL) {
return actions[index];
}
// Momentum events shouldn't run special actions.
if (aEvent->mIsMomentum) {
// Use the default action. Note that user might kill the wheel scrolling.
Init(INDEX_DEFAULT);
if (actions[INDEX_DEFAULT] == ACTION_SCROLL ||
- actions[INDEX_DEFAULT] == ACTION_HORIZONTAL_SCROLL) {
+ actions[INDEX_DEFAULT] == ACTION_HORIZONTALIZED_SCROLL) {
return actions[INDEX_DEFAULT];
}
return ACTION_NONE;
}
return actions[index];
}
@@ -6093,30 +6100,36 @@ bool
EventStateManager::WheelEventIsScrollAction(const WidgetWheelEvent* aEvent)
{
if (aEvent->mMessage != eWheel) {
return false;
}
WheelPrefs::Action action =
WheelPrefs::GetInstance()->ComputeActionFor(aEvent);
return action == WheelPrefs::ACTION_SCROLL ||
- action == WheelPrefs::ACTION_HORIZONTAL_SCROLL;
+ action == WheelPrefs::ACTION_HORIZONTALIZED_SCROLL;
}
// static
-bool
-EventStateManager::WheelEventIsHorizontalScrollAction(
- const WidgetWheelEvent* aEvent)
+WheelDeltaAdjustmentStrategy
+EventStateManager::GetWheelDeltaAdjustmentStrategy(
+ const WidgetWheelEvent& aEvent)
{
- if (aEvent->mMessage != eWheel) {
- return false;
- }
- WheelPrefs::Action action =
- WheelPrefs::GetInstance()->ComputeActionFor(aEvent);
- return action == WheelPrefs::ACTION_HORIZONTAL_SCROLL;
+ if (aEvent.mMessage != eWheel) {
+ return WheelDeltaAdjustmentStrategy::eNone;
+ }
+ switch (WheelPrefs::GetInstance()->ComputeActionFor(&aEvent)) {
+ case WheelPrefs::ACTION_HORIZONTALIZED_SCROLL:
+ return WheelDeltaAdjustmentStrategy::eHorizontalize;
+ // TODO Auto-dir scrolling is going to be handled here while implementing it
+ default:
+ // Prevent compilation errors generated by -Werror=switch
+ break;
+ }
+ return WheelDeltaAdjustmentStrategy::eNone;
}
void
EventStateManager::GetUserPrefsForWheelEvent(const WidgetWheelEvent* aEvent,
double* aOutMultiplierX,
double* aOutMultiplierY)
{
WheelPrefs::GetInstance()->GetUserPrefsForEvent(
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -12,16 +12,17 @@
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/TimeStamp.h"
#include "nsIFrame.h"
#include "Units.h"
+#include "WheelHandlingHelper.h" // for WheelDeltaAdjustmentStrategy
#define NS_USER_INTERACTION_INTERVAL 5000 // ms
class nsFrameLoader;
class nsIContent;
class nsIDocument;
class nsIDocShell;
class nsIDocShellTreeItem;
@@ -303,19 +304,29 @@ public:
// Sets the full-screen event state on aElement to aIsFullScreen.
static void SetFullScreenState(dom::Element* aElement, bool aIsFullScreen);
static bool IsRemoteTarget(nsIContent* aTarget);
// Returns true if the given WidgetWheelEvent will resolve to a scroll action.
static bool WheelEventIsScrollAction(const WidgetWheelEvent* aEvent);
- // Returns true if the given WidgetWheelEvent will resolve to a horizontal
- // scroll action but it's a vertical wheel operation.
- static bool WheelEventIsHorizontalScrollAction(const WidgetWheelEvent* aEvet);
+ // For some kinds of scrollings, the delta values of WidgetWheelEvent are
+ // possbile to be adjusted. This function is used to detect such scrollings
+ // and returns a wheel delta adjustment strategy to use, which is corresponded
+ // to the kind of the scrolling.
+ // It returns WheelDeltaAdjustmentStrategy::eHorizontalize if the current
+ // default action is horizontalized scrolling.
+ // TODO Insert new comment words about the returned value for auto-dir
+ // scrolling while implementing it.
+ // It returns WheelDeltaAdjustmentStrategy::eNone to mean no delta adjustment
+ // strategy should be used if the scrolling is just a tranditional scrolling
+ // whose delta values are never possible to be adjusted.
+ static WheelDeltaAdjustmentStrategy
+ GetWheelDeltaAdjustmentStrategy(const WidgetWheelEvent& aEvent);
// Returns user-set multipliers for a wheel event.
static void GetUserPrefsForWheelEvent(const WidgetWheelEvent* aEvent,
double* aOutMultiplierX,
double* aOutMultiplierY);
// Holds the point in screen coords that a mouse event was dispatched to,
// before we went into pointer lock mode. This is constantly updated while
@@ -558,18 +569,24 @@ protected:
* Computes the default action for the aEvent with the prefs.
*/
enum Action : uint8_t
{
ACTION_NONE = 0,
ACTION_SCROLL,
ACTION_HISTORY,
ACTION_ZOOM,
- ACTION_HORIZONTAL_SCROLL,
- ACTION_LAST = ACTION_HORIZONTAL_SCROLL,
+ // Horizontalized scrolling means treating vertical wheel scrolling as
+ // horizontal scrolling during the process of its default action and
+ // plugins handling scrolling. Note that delta values as the event object
+ // in a DOM event listener won't be affected, and will be still the
+ // original values. For more details, refer to
+ // mozilla::WheelDeltaAdjustmentStrategy::eHorizontalize
+ ACTION_HORIZONTALIZED_SCROLL,
+ ACTION_LAST = ACTION_HORIZONTALIZED_SCROLL,
// Following actions are used only by internal processing. So, cannot
// specified by prefs.
ACTION_SEND_TO_PLUGIN,
};
Action ComputeActionFor(const WidgetWheelEvent* aEvent);
/**
* NeedToComputeLineOrPageDelta() returns if the aEvent needs to be
@@ -628,19 +645,22 @@ protected:
void GetBasePrefName(Index aIndex, nsACString& aBasePrefName);
void Init(Index aIndex);
void Reset();
/**
* Retrieve multiplier for aEvent->mDeltaX and aEvent->mDeltaY.
- * If the default action is ACTION_HORIZONTAL_SCROLL and the delta values
- * are adjusted by AutoWheelDeltaAdjuster(), this treats mMultiplierX as
- * multiplier for deltaY and mMultiplierY as multiplier for deltaY.
+ *
+ * Note that if the default action is ACTION_HORIZONTALIZED_SCROLL and the
+ * delta values have been adjusted by WheelDeltaHorizontalizer() before this
+ * function is called, this function will swap the X and Y multipliers. By
+ * doing this, multipliers will still apply to the delta values they
+ * originally corresponded to.
*
* @param aEvent The event which is being handled.
* @param aIndex The index of mMultiplierX and mMultiplierY.
* Should be result of GetIndexFor(aEvent).
* @param aMultiplierForDeltaX Will be set to multiplier for
* aEvent->mDeltaX.
* @param aMultiplierForDeltaY Will be set to multiplier for
* aEvent->mDeltaY.
--- a/dom/events/WheelHandlingHelper.cpp
+++ b/dom/events/WheelHandlingHelper.cpp
@@ -579,57 +579,62 @@ WheelTransaction::Prefs::InitializeStati
Preferences::AddUintVarCache(&sMouseWheelTransactionIgnoreMoveDelay,
"mousewheel.transaction.ignoremovedelay", 100);
Preferences::AddBoolVarCache(&sTestMouseScroll, "test.mousescroll", false);
sIsInitialized = true;
}
}
/******************************************************************/
-/* mozilla::AutoWheelDeltaAdjuster */
+/* mozilla::WheelDeltaHorizontalizer */
/******************************************************************/
-AutoWheelDeltaAdjuster::AutoWheelDeltaAdjuster(WidgetWheelEvent& aWheelEvent)
- : mWheelEvent(aWheelEvent)
- , mOldDeltaX(aWheelEvent.mDeltaX)
- , mOldDeltaZ(aWheelEvent.mDeltaZ)
- , mOldOverflowDeltaX(aWheelEvent.mOverflowDeltaX)
- , mOldLineOrPageDeltaX(aWheelEvent.mLineOrPageDeltaX)
- , mTreatedVerticalWheelAsHorizontalScroll(false)
+void
+WheelDeltaHorizontalizer::Horizontalize()
{
- MOZ_ASSERT(!aWheelEvent.mDeltaValuesAdjustedForDefaultHandler);
+ MOZ_ASSERT(!mWheelEvent.mDeltaValuesHorizontalizedForDefaultHandler,
+ "Wheel delta values in one wheel scroll event are being adjusted "
+ "a second time");
+
+ // Log the old values.
+ mOldDeltaX = mWheelEvent.mDeltaX;
+ mOldDeltaZ = mWheelEvent.mDeltaZ;
+ mOldOverflowDeltaX = mWheelEvent.mOverflowDeltaX;
+ mOldLineOrPageDeltaX = mWheelEvent.mLineOrPageDeltaX;
- if (EventStateManager::WheelEventIsHorizontalScrollAction(&aWheelEvent)) {
- // Move deltaY values to deltaX and set both deltaY and deltaZ to 0.
- mWheelEvent.mDeltaX = mWheelEvent.mDeltaY;
- mWheelEvent.mDeltaY = 0.0;
- mWheelEvent.mDeltaZ = 0.0;
- mWheelEvent.mOverflowDeltaX = mWheelEvent.mOverflowDeltaY;
- mWheelEvent.mOverflowDeltaY = 0.0;
- mWheelEvent.mLineOrPageDeltaX = mWheelEvent.mLineOrPageDeltaY;
- mWheelEvent.mLineOrPageDeltaY = 0;
- mWheelEvent.mDeltaValuesAdjustedForDefaultHandler = true;
- mTreatedVerticalWheelAsHorizontalScroll = true;
- }
+ // Move deltaY values to deltaX and set both deltaY and deltaZ to 0.
+ mWheelEvent.mDeltaX = mWheelEvent.mDeltaY;
+ mWheelEvent.mDeltaY = 0.0;
+ mWheelEvent.mDeltaZ = 0.0;
+ mWheelEvent.mOverflowDeltaX = mWheelEvent.mOverflowDeltaY;
+ mWheelEvent.mOverflowDeltaY = 0.0;
+ mWheelEvent.mLineOrPageDeltaX = mWheelEvent.mLineOrPageDeltaY;
+ mWheelEvent.mLineOrPageDeltaY = 0;
+
+ // Mark it horizontalized in order to restore the delta values when this
+ // instance is being destroyed.
+ mWheelEvent.mDeltaValuesHorizontalizedForDefaultHandler = true;
+ mHorizontalized = true;
}
-void AutoWheelDeltaAdjuster::CancelAdjustment()
+void WheelDeltaHorizontalizer::CancelHorizontalization()
{
- if (mTreatedVerticalWheelAsHorizontalScroll &&
- mWheelEvent.mDeltaValuesAdjustedForDefaultHandler) {
+ // Restore the horizontalized delta.
+ if (mHorizontalized &&
+ mWheelEvent.mDeltaValuesHorizontalizedForDefaultHandler) {
mWheelEvent.mDeltaY = mWheelEvent.mDeltaX;
mWheelEvent.mDeltaX = mOldDeltaX;
mWheelEvent.mDeltaZ = mOldDeltaZ;
mWheelEvent.mOverflowDeltaY = mWheelEvent.mOverflowDeltaX;
mWheelEvent.mOverflowDeltaX = mOldOverflowDeltaX;
mWheelEvent.mLineOrPageDeltaY = mWheelEvent.mLineOrPageDeltaX;
mWheelEvent.mLineOrPageDeltaX = mOldLineOrPageDeltaX;
- mWheelEvent.mDeltaValuesAdjustedForDefaultHandler = false;
- mTreatedVerticalWheelAsHorizontalScroll = false;
+ mWheelEvent.mDeltaValuesHorizontalizedForDefaultHandler = false;
+ mHorizontalized = false;
}
}
-AutoWheelDeltaAdjuster::~AutoWheelDeltaAdjuster()
+WheelDeltaHorizontalizer::~WheelDeltaHorizontalizer()
{
- CancelAdjustment();
+ CancelHorizontalization();
}
} // namespace mozilla
--- a/dom/events/WheelHandlingHelper.h
+++ b/dom/events/WheelHandlingHelper.h
@@ -205,41 +205,73 @@ protected:
static int32_t sMouseWheelAccelerationStart;
static int32_t sMouseWheelAccelerationFactor;
static uint32_t sMouseWheelTransactionTimeout;
static uint32_t sMouseWheelTransactionIgnoreMoveDelay;
static bool sTestMouseScroll;
};
};
+// For some kinds of scrollings, the delta values of WidgetWheelEvent are
+// possbile to be adjusted. For example, the user has configured the pref to let
+// [vertical wheel + Shift key] to perform horizontal scrolling instead of
+// vertical scrolling.
+// The values in this enumeration list all kinds of scrollings whose delta
+// values are possible to be adjusted.
+enum class WheelDeltaAdjustmentStrategy : uint8_t
+{
+ // There is no strategy, don't adjust delta values in any cases.
+ eNone,
+ // This strategy means we're receiving a horizontalized scroll, so we should
+ // apply horizontalization strategy for its delta values.
+ // Horizontalized scrolling means treating vertical wheel scrolling as
+ // horizontal scrolling by adjusting delta values.
+ // It's important to keep in mind with the percise concept of horizontalized
+ // scrolling: Delta values are *ONLY* going to be adjusted during the process
+ // of its default action handling; in views of any programmes other than the
+ // default action handler, such as a DOM event listener or a plugin, delta
+ // values are never going to be adjusted, they will still retrive original
+ // delta values when horizontalization occured for default actions.
+ eHorizontalize,
+ // TODO A new value for auto-dir scrolling is going to be added while
+ // implementing such scrolling.
+};
+
/**
- * When a wheel event should be treated as specially, e.g., it's a vertical
- * wheel operation but user wants to scroll the target horizontally, this
- * class adjust the delta values automatically. Then, restores the original
- * value when the instance is destroyed.
+ * When a *pure* vertical wheel event should be treated as if it was a
+ * horizontal scroll because the user wants to horizontalize the wheel scroll,
+ * an instance of this class will adjust the delta values upon calling
+ * Horizontalize(). And the horizontalized delta values will be restored
+ * automatically when the instance of this class is being destructed. Or you can
+ * restore them in advance by calling CancelHorizontalization().
*/
-class MOZ_STACK_CLASS AutoWheelDeltaAdjuster final
+class MOZ_STACK_CLASS WheelDeltaHorizontalizer final
{
public:
/**
- * @param aWheelEvent A wheel event. The delta values may be
- * modified for default handler.
- * Its mDeltaValuesAdjustedForDefaultHandler
- * must not be true because if it's true,
- * the event has already been adjusted the
- * delta values for default handler.
+ * @param aWheelEvent A wheel event whose delta values will be adjusted
+ * upon calling Horizontalize().
*/
- explicit AutoWheelDeltaAdjuster(WidgetWheelEvent& aWheelEvent);
- ~AutoWheelDeltaAdjuster();
- void CancelAdjustment();
+ explicit WheelDeltaHorizontalizer(WidgetWheelEvent& aWheelEvent)
+ : mWheelEvent(aWheelEvent)
+ , mHorizontalized(false)
+ {
+ }
+ /**
+ * Converts vertical scrolling into horizontal scrolling by adjusting the
+ * its delta values.
+ */
+ void Horizontalize();
+ ~WheelDeltaHorizontalizer();
+ void CancelHorizontalization();
private:
WidgetWheelEvent& mWheelEvent;
double mOldDeltaX;
double mOldDeltaZ;
double mOldOverflowDeltaX;
int32_t mOldLineOrPageDeltaX;
- bool mTreatedVerticalWheelAsHorizontalScroll;
+ bool mHorizontalized;
};
} // namespace mozilla
#endif // mozilla_WheelHandlingHelper_h_
--- a/dom/events/test/window_wheel_default_action.html
+++ b/dom/events/test/window_wheel_default_action.html
@@ -73,21 +73,21 @@ SimpleTest.requestFlakyTimeout("untriage
var winUtils = SpecialPowers.getDOMWindowUtils(window);
// grab refresh driver
winUtils.advanceTimeAndRefresh(100);
var gScrollableElement = document.getElementById("scrollable");
var gScrolledElement = document.getElementById("scrolled");
var gSpacerForBodyElement = document.getElementById("spacerForBody");
-const kDefaultActionNone = 0;
-const kDefaultActionScroll = 1;
-const kDefaultActionHistory = 2;
-const kDefaultActionZoom = 3;
-const kDefaultActionHorizontalScroll = 4;
+const kDefaultActionNone = 0;
+const kDefaultActionScroll = 1;
+const kDefaultActionHistory = 2;
+const kDefaultActionZoom = 3;
+const kDefaultActionHorizontalizedScroll = 4;
const kDefaultActionOverrideXNoOverride = -1;
const kDefaultActionOverrideXNone = kDefaultActionNone;
const kDefaultActionOverrideXScroll = kDefaultActionScroll;
const kDefaultActionOverrideXHistory = kDefaultActionHistory;
const kDefaultActionOverrideXZoom = kDefaultActionZoom;
function is()
@@ -953,17 +953,17 @@ function doTestScroll(aSettings, aCallba
winUtils.advanceTimeAndRefresh(100);
doNextTest();
}
});
}
doNextTest();
}
-function doTestHorizontalScroll(aSettings, aCallback)
+function doTestHorizontalizedScroll(aSettings, aCallback)
{
const kNoScroll = 0x00;
const kScrollLeft = 0x01;
const kScrollRight = 0x02;
const kTests = [
{ description: "Scroll to right by pixel scroll even if lineOrPageDelta is 0",
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
@@ -1255,17 +1255,17 @@ function doTestHorizontalScroll(aSetting
SimpleTest.executeSoon(aCallback);
return;
}
gScrollableElement.scrollTop = 1000;
gScrollableElement.scrollLeft = 1000;
var currentTest = kTests[currentTestIndex];
- description = "doTestHorizontalScroll(aSettings=" + aSettings.description + "), " + currentTest.description + ": ";
+ description = "doTestHorizontalizedScroll(aSettings=" + aSettings.description + "), " + currentTest.description + ": ";
if (currentTest.prepare) {
currentTest.prepare(doTestCurrentScroll);
} else {
doTestCurrentScroll();
}
}
function doTestCurrentScroll() {
@@ -2173,17 +2173,17 @@ function doTestActionOverride(aCallback)
function runTests()
{
SpecialPowers.pushPrefEnv({"set": [
["test.events.async.enabled", true],
["general.smoothScroll", false],
["mousewheel.default.action", kDefaultActionScroll],
["mousewheel.default.action.override_x", kDefaultActionOverrideXNoOverride],
- ["mousewheel.with_shift.action", kDefaultActionHorizontalScroll],
+ ["mousewheel.with_shift.action", kDefaultActionHorizontalizedScroll],
["mousewheel.with_shift.action.override_x", kDefaultActionOverrideXNoOverride],
["mousewheel.with_control.action", kDefaultActionZoom],
["mousewheel.with_control.action.override_x", kDefaultActionOverrideXNoOverride],
["mousewheel.with_alt.action", kDefaultActionHistory],
["mousewheel.with_alt.action.override_x", kDefaultActionOverrideXNoOverride]]},
runTests2);
}
@@ -2212,17 +2212,17 @@ function runTests2()
deltaMultiplierX: 1.0, deltaMultiplierY: 1.0, deltaMultiplierZ: -2.0 },
];
var index = 0;
function doTest() {
setDeltaMultiplierSettings(kSettings[index], function () {
doTestScroll(kSettings[index], function () {
- doTestHorizontalScroll(kSettings[index], function() {
+ doTestHorizontalizedScroll(kSettings[index], function() {
doTestZoom(kSettings[index], function() {
if (++index == kSettings.length) {
setDeltaMultiplierSettings(kSettings[0], function() {
doTestZoomedScroll(function() {
doTestWholeScroll(function() {
doTestActionOverride(function() {
finishTests();
});
--- a/gfx/layers/apz/src/APZInputBridge.cpp
+++ b/gfx/layers/apz/src/APZInputBridge.cpp
@@ -3,23 +3,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/APZInputBridge.h"
#include "gfxPrefs.h" // for gfxPrefs
#include "InputData.h" // for MouseInput, etc
+#include "mozilla/dom/WheelEventBinding.h" // for WheelEvent constants
#include "mozilla/EventStateManager.h" // for EventStateManager
#include "mozilla/layers/APZThreadUtils.h" // for AssertOnControllerThread, etc
#include "mozilla/MouseEvents.h" // for WidgetMouseEvent
#include "mozilla/TextEvents.h" // for WidgetKeyboardEvent
#include "mozilla/TouchEvents.h" // for WidgetTouchEvent
-#include "mozilla/WheelHandlingHelper.h" // for AutoWheelDeltaAdjuster
-#include "mozilla/dom/WheelEventBinding.h" // for WheelEvent constants
+#include "mozilla/WheelHandlingHelper.h" // for WheelDeltaHorizontalizer,
+ // WheelDeltaAdjustmentStrategy
namespace mozilla {
namespace layers {
static bool
WillHandleMouseEvent(const WidgetMouseEventBase& aEvent)
{
return aEvent.mMessage == eMouseMove ||
@@ -111,20 +112,28 @@ APZInputBridge::ReceiveInputEvent(
((wheelEvent.mDeltaMode == dom::WheelEventBinding::DOM_DELTA_LINE &&
gfxPrefs::WheelSmoothScrollEnabled()) ||
(wheelEvent.mDeltaMode == dom::WheelEventBinding::DOM_DELTA_PAGE &&
gfxPrefs::PageSmoothScrollEnabled())))
{
scrollMode = ScrollWheelInput::SCROLLMODE_SMOOTH;
}
- // AutoWheelDeltaAdjuster may adjust the delta values for default
- // action hander. The delta values will be restored automatically
- // when its instance is destroyed.
- AutoWheelDeltaAdjuster adjuster(wheelEvent);
+ WheelDeltaAdjustmentStrategy strategy =
+ EventStateManager::GetWheelDeltaAdjustmentStrategy(wheelEvent);
+ // Adjust the delta values of the wheel event if the current default
+ // action is to horizontalize scrolling. I.e., deltaY values are set to
+ // deltaX and deltaY and deltaZ values are set to 0.
+ // If horizontalized, the delta values will be restored and its overflow
+ // deltaX will become 0 when the WheelDeltaHorizontalizer instance is
+ // being destroyed.
+ WheelDeltaHorizontalizer horizontalizer(wheelEvent);
+ if (WheelDeltaAdjustmentStrategy::eHorizontalize == strategy) {
+ horizontalizer.Horizontalize();
+ }
// If the wheel event becomes no-op event, don't handle it as scroll.
if (wheelEvent.mDeltaX || wheelEvent.mDeltaY) {
ScreenPoint origin(wheelEvent.mRefPoint.x, wheelEvent.mRefPoint.y);
ScrollWheelInput input(wheelEvent.mTime, wheelEvent.mTimeStamp, 0,
scrollMode,
ScrollWheelInput::DeltaTypeForDeltaMode(
wheelEvent.mDeltaMode),
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -825,16 +825,29 @@ protected:
// Protects |mFrameMetrics|, |mLastContentPaintMetrics|, and |mState|.
// Before manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the
// monitor should be held. When setting |mState|, either the SetState()
// function can be used, or the monitor can be held and then |mState| updated.
// IMPORTANT: See the note about lock ordering at the top of APZCTreeManager.h.
// This is mutable to allow entering it from 'const' methods; doing otherwise
// would significantly limit what methods could be 'const'.
+ // FIXME: Please keep in mind that due to some existing coupled relationships
+ // among the class members, we should be aware of indirect usage of the
+ // monitor-protected members. That is, although this monitor isn't required to
+ // be held before manipulating non-protected class members, some functions on
+ // those members might indirectly manipulate the protected members; in such
+ // cases, the monitor should still be held. Let's take mX.CanScroll for
+ // example:
+ // Axis::CanScroll(ParentLayerCoord) calls Axis::CanScroll() which calls
+ // Axis::GetPageLength() which calls Axis::GetFrameMetrics() which calls
+ // AsyncPanZoomController::GetFrameMetrics(), therefore, this monitor should
+ // be held before calling the CanScroll function of |mX| and |mY|. These
+ // coupled relationships bring us the burden of taking care of when the
+ // monitor should be held, so they should be decoupled in the future.
mutable RecursiveMutex mRecursiveMutex;
private:
// Metadata of the container layer corresponding to this APZC. This is
// stored here so that it is accessible from the UI/controller thread.
// These are the metrics at last content paint, the most recent
// values we were notified of in NotifyLayersUpdate(). Since it represents
// the Gecko state, it should be used as a basis for untransformation when
--- a/widget/InputData.h
+++ b/widget/InputData.h
@@ -584,16 +584,20 @@ public:
bool mAllowToOverrideSystemScrollSpeed;
};
class KeyboardInput : public InputData
{
public:
typedef mozilla::layers::KeyboardScrollAction KeyboardScrollAction;
+ // Note that if you change the first member in this enum(I.e. KEY_DOWN) to one
+ // other member, don't forget to update the minimum value in
+ // ContiguousEnumSerializer for KeyboardEventType in widget/nsGUIEventIPC
+ // accordingly.
enum KeyboardEventType
{
KEY_DOWN,
KEY_PRESS,
KEY_UP,
// Any other key event such as eKeyDownOnPlugin
KEY_OTHER,
--- a/widget/MouseEvents.h
+++ b/widget/MouseEvents.h
@@ -513,17 +513,17 @@ private:
, mScrollType(SCROLL_DEFAULT)
, mCustomizedByUserPrefs(false)
, mMayHaveMomentum{ false }
, mIsMomentum(false)
, mIsNoLineOrPageDelta(false)
, mViewPortIsOverscrolled(false)
, mCanTriggerSwipe(false)
, mAllowToOverrideSystemScrollSpeed(false)
- , mDeltaValuesAdjustedForDefaultHandler(false)
+ , mDeltaValuesHorizontalizedForDefaultHandler(false)
{
}
public:
virtual WidgetWheelEvent* AsWheelEvent() override { return this; }
WidgetWheelEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
: WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, eWheelEventClass)
@@ -540,17 +540,17 @@ public:
, mScrollType(SCROLL_DEFAULT)
, mCustomizedByUserPrefs(false)
, mMayHaveMomentum(false)
, mIsMomentum(false)
, mIsNoLineOrPageDelta(false)
, mViewPortIsOverscrolled(false)
, mCanTriggerSwipe(false)
, mAllowToOverrideSystemScrollSpeed(true)
- , mDeltaValuesAdjustedForDefaultHandler(false)
+ , mDeltaValuesHorizontalizedForDefaultHandler(false)
{
}
virtual WidgetEvent* Duplicate() const override
{
MOZ_ASSERT(mClass == eWheelEventClass,
"Duplicate() must be overridden by sub class");
// Not copying widget, it is a weak reference.
@@ -574,18 +574,18 @@ public:
// mousewheel.*.delta_multiplier_* prefs which are applied by
// EventStateManager. So, after widget dispatches this event,
// these delta values may have different values than before.
double mDeltaX;
double mDeltaY;
double mDeltaZ;
// overflowed delta values for scroll, these values are set by
- // nsEventStateManger. If the default action of the wheel event isn't scroll,
- // these values always zero. Otherwise, remaning delta values which are
+ // EventStateManger. If the default action of the wheel event isn't scroll,
+ // these values are always zero. Otherwise, remaining delta values which are
// not used by scroll are set.
// NOTE: mDeltaX, mDeltaY and mDeltaZ may be modified by EventStateManager.
// However, mOverflowDeltaX and mOverflowDeltaY indicate unused original
// delta values which are not applied the delta_multiplier prefs.
// So, if widget wanted to know the actual direction to be scrolled,
// it would need to check the mDeltaX and mDeltaY.
double mOverflowDeltaX;
double mOverflowDeltaY;
@@ -658,19 +658,20 @@ public:
// viewport.
bool mCanTriggerSwipe;
// If mAllowToOverrideSystemScrollSpeed is true, the scroll speed may be
// overridden. Otherwise, the scroll speed won't be overridden even if
// it's enabled by the pref.
bool mAllowToOverrideSystemScrollSpeed;
- // While default handler handles a wheel event specially (e.g., treating
- // mDeltaY as horizontal scroll), this is set to true.
- bool mDeltaValuesAdjustedForDefaultHandler;
+ // After the event's default action handler has adjusted its delta's values
+ // for horizontalizing a vertical wheel scroll, this variable will be set to
+ // true.
+ bool mDeltaValuesHorizontalizedForDefaultHandler;
void AssignWheelEventData(const WidgetWheelEvent& aEvent, bool aCopyTargets)
{
AssignMouseEventBaseData(aEvent, aCopyTargets);
mDeltaX = aEvent.mDeltaX;
mDeltaY = aEvent.mDeltaY;
mDeltaZ = aEvent.mDeltaZ;
@@ -683,18 +684,18 @@ public:
mLineOrPageDeltaY = aEvent.mLineOrPageDeltaY;
mScrollType = aEvent.mScrollType;
mOverflowDeltaX = aEvent.mOverflowDeltaX;
mOverflowDeltaY = aEvent.mOverflowDeltaY;
mViewPortIsOverscrolled = aEvent.mViewPortIsOverscrolled;
mCanTriggerSwipe = aEvent.mCanTriggerSwipe;
mAllowToOverrideSystemScrollSpeed =
aEvent.mAllowToOverrideSystemScrollSpeed;
- mDeltaValuesAdjustedForDefaultHandler =
- aEvent.mDeltaValuesAdjustedForDefaultHandler;
+ mDeltaValuesHorizontalizedForDefaultHandler =
+ aEvent.mDeltaValuesHorizontalizedForDefaultHandler;
}
// System scroll speed settings may be too slow at using Gecko. In such
// case, we should override the scroll speed computed with system settings.
// Following methods return preferred delta values which are multiplied by
// factors specified by prefs. If system scroll speed shouldn't be
// overridden (e.g., this feature is disabled by pref), they return raw
// delta values.
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -182,17 +182,17 @@ struct ParamTraits<mozilla::WidgetWheelE
WriteParam(aMsg, aParam.mLineOrPageDeltaX);
WriteParam(aMsg, aParam.mLineOrPageDeltaY);
WriteParam(aMsg, static_cast<uint8_t>(aParam.mScrollType));
WriteParam(aMsg, aParam.mOverflowDeltaX);
WriteParam(aMsg, aParam.mOverflowDeltaY);
WriteParam(aMsg, aParam.mViewPortIsOverscrolled);
WriteParam(aMsg, aParam.mCanTriggerSwipe);
WriteParam(aMsg, aParam.mAllowToOverrideSystemScrollSpeed);
- WriteParam(aMsg, aParam.mDeltaValuesAdjustedForDefaultHandler);
+ WriteParam(aMsg, aParam.mDeltaValuesHorizontalizedForDefaultHandler);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
uint8_t scrollType = 0;
bool rv =
ReadParam(aMsg, aIter,
static_cast<mozilla::WidgetMouseEventBase*>(aResult)) &&
@@ -207,17 +207,18 @@ struct ParamTraits<mozilla::WidgetWheelE
ReadParam(aMsg, aIter, &aResult->mLineOrPageDeltaX) &&
ReadParam(aMsg, aIter, &aResult->mLineOrPageDeltaY) &&
ReadParam(aMsg, aIter, &scrollType) &&
ReadParam(aMsg, aIter, &aResult->mOverflowDeltaX) &&
ReadParam(aMsg, aIter, &aResult->mOverflowDeltaY) &&
ReadParam(aMsg, aIter, &aResult->mViewPortIsOverscrolled) &&
ReadParam(aMsg, aIter, &aResult->mCanTriggerSwipe) &&
ReadParam(aMsg, aIter, &aResult->mAllowToOverrideSystemScrollSpeed) &&
- ReadParam(aMsg, aIter, &aResult->mDeltaValuesAdjustedForDefaultHandler);
+ ReadParam(aMsg, aIter,
+ &aResult->mDeltaValuesHorizontalizedForDefaultHandler);
aResult->mScrollType =
static_cast<mozilla::WidgetWheelEvent::ScrollType>(scrollType);
return rv;
}
};
template<>
struct ParamTraits<mozilla::WidgetPointerHelper>