зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1351783 part 16 - Perform async scrolling for keyboard events when possible. r=kats,botond,dvander
This commit ties it all together by dispatching keyboard actions to scroll targets in response to keyboard inputs when we have current and valid focus state. MozReview-Commit-ID: G7rZiS3FH5e --HG-- extra : rebase_source : 10129d417fe8ef576cac5bda3157dd8f65b5843a extra : histedit_source : be651a33f787f68bc764988ddc073d346e854491
This commit is contained in:
Родитель
c24e099b23
Коммит
db5f497c0f
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/EventStateManager.h" // for WheelPrefs
|
||||
#include "mozilla/layers/APZThreadUtils.h" // for AssertOnCompositorThread, etc
|
||||
#include "mozilla/MouseEvents.h" // for WidgetMouseEvent
|
||||
#include "mozilla/TextEvents.h" // for WidgetKeyboardEvent
|
||||
#include "mozilla/TouchEvents.h" // for WidgetTouchEvent
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -144,6 +145,17 @@ IAPZCTreeManager::ReceiveInputEvent(
|
|||
return nsEventStatus_eIgnore;
|
||||
|
||||
}
|
||||
case eKeyboardEventClass: {
|
||||
WidgetKeyboardEvent& keyboardEvent = *aEvent.AsKeyboardEvent();
|
||||
|
||||
KeyboardInput input(keyboardEvent);
|
||||
|
||||
nsEventStatus status = ReceiveInputEvent(input, aOutTargetGuid, aOutInputBlockId);
|
||||
|
||||
keyboardEvent.mFlags.mHandledByAPZ = input.mHandledByAPZ;
|
||||
keyboardEvent.mFocusSequenceNumber = input.mFocusSequenceNumber;
|
||||
return status;
|
||||
}
|
||||
default: {
|
||||
|
||||
UpdateWheelTransaction(aEvent.mRefPoint, aEvent.mMessage);
|
||||
|
|
|
@ -1240,6 +1240,91 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
|
|||
apzc->GetGuid(aOutTargetGuid);
|
||||
tapInput.mPoint = *untransformedPoint;
|
||||
}
|
||||
break;
|
||||
} case KEYBOARD_INPUT: {
|
||||
// Disable async keyboard scrolling when accessibility.browsewithcaret is enabled
|
||||
if (!gfxPrefs::APZKeyboardEnabled() ||
|
||||
gfxPrefs::AccessibilityBrowseWithCaret()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
KeyboardInput& keyInput = aEvent.AsKeyboardInput();
|
||||
|
||||
// Try and find a matching shortcut for this keyboard input
|
||||
Maybe<KeyboardShortcut> shortcut = mKeyboardMap.FindMatch(keyInput);
|
||||
|
||||
if (!shortcut) {
|
||||
// If we don't have a shortcut for this key event, then we can keep our focus
|
||||
// only if we know there are no key event listeners for this target
|
||||
if (mFocusState.CanIgnoreKeyboardShortcutMisses()) {
|
||||
focusSetter.MarkAsNonFocusChanging();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if this shortcut needs to be dispatched to content. Anything matching
|
||||
// this is assumed to be able to change focus.
|
||||
if (shortcut->mDispatchToContent) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// We know we have an action to execute on whatever is the current focus target
|
||||
const KeyboardScrollAction& action = shortcut->mAction;
|
||||
|
||||
// The current focus target depends on which direction the scroll is to happen
|
||||
Maybe<ScrollableLayerGuid> targetGuid;
|
||||
switch (action.mType)
|
||||
{
|
||||
case KeyboardScrollAction::eScrollCharacter: {
|
||||
targetGuid = mFocusState.GetHorizontalTarget();
|
||||
break;
|
||||
}
|
||||
case KeyboardScrollAction::eScrollLine:
|
||||
case KeyboardScrollAction::eScrollPage:
|
||||
case KeyboardScrollAction::eScrollComplete: {
|
||||
targetGuid = mFocusState.GetVerticalTarget();
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyboardScrollAction::eSentinel: {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid KeyboardScrollActionType");
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have a scroll target then either we have a stale focus target,
|
||||
// the focused element has event listeners, or the focused element doesn't have a
|
||||
// layerized scroll frame. In any case we need to dispatch to content.
|
||||
if (!targetGuid) {
|
||||
return result;
|
||||
}
|
||||
|
||||
RefPtr<AsyncPanZoomController> targetApzc = GetTargetAPZC(targetGuid->mLayersId,
|
||||
targetGuid->mScrollId);
|
||||
|
||||
// Scroll snapping behavior with keyboard input is more complicated, so
|
||||
// ignore any input events that are targeted at an Apzc with scroll snap
|
||||
// points.
|
||||
if (!targetApzc || targetApzc->HasScrollSnapping()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Attach the keyboard scroll action to the input event for processing
|
||||
// by the input queue.
|
||||
keyInput.mAction = action;
|
||||
|
||||
// Dispatch the event to the input queue.
|
||||
result = mInputQueue->ReceiveInputEvent(
|
||||
targetApzc,
|
||||
/* aTargetConfirmed = */ true,
|
||||
keyInput, aOutInputBlockId);
|
||||
|
||||
// Any keyboard event that is dispatched to the input queue at this point
|
||||
// should have been consumed
|
||||
MOZ_ASSERT(result == nsEventStatus_eConsumeNoDefault);
|
||||
|
||||
keyInput.mHandledByAPZ = true;
|
||||
focusSetter.MarkAsNonFocusChanging();
|
||||
|
||||
break;
|
||||
} case SENTINEL_INPUT: {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid InputType.");
|
||||
|
|
|
@ -340,6 +340,13 @@ public:
|
|||
*/
|
||||
bool HasScrollgrab() const { return mScrollMetadata.GetHasScrollgrab(); }
|
||||
|
||||
/**
|
||||
* Returns whether this APZC has scroll snap points.
|
||||
*/
|
||||
bool HasScrollSnapping() const {
|
||||
return mScrollMetadata.GetSnapInfo().HasScrollSnapping();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this APZC has room to be panned (in any direction).
|
||||
*/
|
||||
|
|
|
@ -113,5 +113,35 @@ FocusState::RemoveFocusTarget(uint64_t aLayersId)
|
|||
mFocusTree.erase(aLayersId);
|
||||
}
|
||||
|
||||
Maybe<ScrollableLayerGuid>
|
||||
FocusState::GetHorizontalTarget() const
|
||||
{
|
||||
// There is not a scrollable layer to async scroll if
|
||||
// 1. We aren't current
|
||||
// 2. There are event listeners that could change the focus
|
||||
// 3. The target has not been layerized
|
||||
if (!IsCurrent() ||
|
||||
mFocusHasKeyEventListeners ||
|
||||
mFocusHorizontalTarget == FrameMetrics::NULL_SCROLL_ID) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(ScrollableLayerGuid(mFocusLayersId, 0, mFocusHorizontalTarget));
|
||||
}
|
||||
|
||||
Maybe<ScrollableLayerGuid>
|
||||
FocusState::GetVerticalTarget() const
|
||||
{
|
||||
// There is not a scrollable layer to async scroll if:
|
||||
// 1. We aren't current
|
||||
// 2. There are event listeners that could change the focus
|
||||
// 3. The target has not been layerized
|
||||
if (!IsCurrent() ||
|
||||
mFocusHasKeyEventListeners ||
|
||||
mFocusVerticalTarget == FrameMetrics::NULL_SCROLL_ID) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(ScrollableLayerGuid(mFocusLayersId, 0, mFocusVerticalTarget));
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -115,6 +115,31 @@ public:
|
|||
*/
|
||||
void RemoveFocusTarget(uint64_t aLayersId);
|
||||
|
||||
/**
|
||||
* Gets the scrollable layer that should be horizontally scrolled for a key
|
||||
* event, if any. The returned ScrollableLayerGuid doesn't contain a presShellId,
|
||||
* and so it should not be used in comparisons.
|
||||
*
|
||||
* No scrollable layer is returned if any of the following are true:
|
||||
* 1. We don't have a current focus target
|
||||
* 2. There are event listeners that could change the focus
|
||||
* 3. The target has not been layerized
|
||||
*/
|
||||
Maybe<ScrollableLayerGuid> GetHorizontalTarget() const;
|
||||
/**
|
||||
* The same as GetHorizontalTarget() but for vertical scrolling.
|
||||
*/
|
||||
Maybe<ScrollableLayerGuid> GetVerticalTarget() const;
|
||||
|
||||
/**
|
||||
* Gets whether it is safe to not increment the focus sequence number for an
|
||||
* unmatched keyboard event.
|
||||
*/
|
||||
bool CanIgnoreKeyboardShortcutMisses() const
|
||||
{
|
||||
return IsCurrent() && !mFocusHasKeyEventListeners;
|
||||
}
|
||||
|
||||
private:
|
||||
// The set of focus targets received indexed by their layer tree ID
|
||||
std::unordered_map<uint64_t, FocusTarget> mFocusTree;
|
||||
|
|
|
@ -870,5 +870,10 @@ TouchBlockState::GetActiveTouchCount() const
|
|||
return mTouchCounter.GetActiveTouchCount();
|
||||
}
|
||||
|
||||
KeyboardBlockState::KeyboardBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc)
|
||||
: InputBlockState(aTargetApzc, true)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -27,6 +27,7 @@ class TouchBlockState;
|
|||
class WheelBlockState;
|
||||
class DragBlockState;
|
||||
class PanGestureBlockState;
|
||||
class KeyboardBlockState;
|
||||
|
||||
/**
|
||||
* A base class that stores state common to various input blocks.
|
||||
|
@ -68,6 +69,9 @@ public:
|
|||
virtual PanGestureBlockState* AsPanGestureBlock() {
|
||||
return nullptr;
|
||||
}
|
||||
virtual KeyboardBlockState* AsKeyboardBlock() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||
TargetConfirmationState aState,
|
||||
|
@ -486,6 +490,23 @@ private:
|
|||
TouchCounter& mTouchCounter;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents a set of keyboard inputs targeted at the same Apzc.
|
||||
*/
|
||||
class KeyboardBlockState : public InputBlockState
|
||||
{
|
||||
public:
|
||||
explicit KeyboardBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc);
|
||||
|
||||
KeyboardBlockState* AsKeyboardBlock() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
bool MustStayActive() override {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -56,6 +56,14 @@ InputQueue::ReceiveInputEvent(const RefPtr<AsyncPanZoomController>& aTarget,
|
|||
return ReceiveMouseInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
|
||||
}
|
||||
|
||||
case KEYBOARD_INPUT: {
|
||||
// Every keyboard input must have a confirmed target
|
||||
MOZ_ASSERT(aTarget && aTargetConfirmed);
|
||||
|
||||
const KeyboardInput& event = aEvent.AsKeyboardInput();
|
||||
return ReceiveKeyboardInput(aTarget, event, aOutInputBlockId);
|
||||
}
|
||||
|
||||
default:
|
||||
// The return value for non-touch input is only used by tests, so just pass
|
||||
// through the return value for now. This can be changed later if needed.
|
||||
|
@ -268,6 +276,39 @@ InputQueue::ReceiveScrollWheelInput(const RefPtr<AsyncPanZoomController>& aTarge
|
|||
return nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
|
||||
nsEventStatus
|
||||
InputQueue::ReceiveKeyboardInput(const RefPtr<AsyncPanZoomController>& aTarget,
|
||||
const KeyboardInput& aEvent,
|
||||
uint64_t* aOutInputBlockId) {
|
||||
KeyboardBlockState* block = mActiveKeyboardBlock.get();
|
||||
|
||||
// If the block is targeting a different Apzc than this keyboard event then
|
||||
// we'll create a new input block
|
||||
if (block && block->GetTargetApzc() != aTarget) {
|
||||
block = nullptr;
|
||||
}
|
||||
|
||||
if (!block) {
|
||||
block = new KeyboardBlockState(aTarget);
|
||||
INPQ_LOG("started new keyboard block %p id %" PRIu64 " for target %p\n",
|
||||
block, block->GetBlockId(), aTarget.get());
|
||||
|
||||
mActiveKeyboardBlock = block;
|
||||
} else {
|
||||
INPQ_LOG("received new event in block %p\n", block);
|
||||
}
|
||||
|
||||
if (aOutInputBlockId) {
|
||||
*aOutInputBlockId = block->GetBlockId();
|
||||
}
|
||||
|
||||
mQueuedInputs.AppendElement(MakeUnique<QueuedInput>(aEvent, *block));
|
||||
|
||||
ProcessQueue();
|
||||
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
static bool
|
||||
CanScrollTargetHorizontally(const PanGestureInput& aInitialEvent,
|
||||
PanGestureBlockState* aBlock)
|
||||
|
@ -461,6 +502,13 @@ InputQueue::GetCurrentPanGestureBlock() const
|
|||
return block ? block->AsPanGestureBlock() : mActivePanGestureBlock.get();
|
||||
}
|
||||
|
||||
KeyboardBlockState*
|
||||
InputQueue::GetCurrentKeyboardBlock() const
|
||||
{
|
||||
InputBlockState* block = GetCurrentBlock();
|
||||
return block ? block->AsKeyboardBlock() : mActiveKeyboardBlock.get();
|
||||
}
|
||||
|
||||
WheelBlockState*
|
||||
InputQueue::GetActiveWheelTransaction() const
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ class TouchBlockState;
|
|||
class WheelBlockState;
|
||||
class DragBlockState;
|
||||
class PanGestureBlockState;
|
||||
class KeyboardBlockState;
|
||||
class AsyncDragMetrics;
|
||||
class QueuedInput;
|
||||
|
||||
|
@ -106,6 +107,7 @@ public:
|
|||
WheelBlockState* GetCurrentWheelBlock() const;
|
||||
DragBlockState* GetCurrentDragBlock() const;
|
||||
PanGestureBlockState* GetCurrentPanGestureBlock() const;
|
||||
KeyboardBlockState* GetCurrentKeyboardBlock() const;
|
||||
/**
|
||||
* Returns true iff the pending block at the head of the queue is a touch
|
||||
* block and is ready for handling.
|
||||
|
@ -169,6 +171,9 @@ private:
|
|||
bool aTargetConfirmed,
|
||||
const PanGestureInput& aEvent,
|
||||
uint64_t* aOutInputBlockId);
|
||||
nsEventStatus ReceiveKeyboardInput(const RefPtr<AsyncPanZoomController>& aTarget,
|
||||
const KeyboardInput& aEvent,
|
||||
uint64_t* aOutInputBlockId);
|
||||
|
||||
/**
|
||||
* Helper function that searches mQueuedInputs for the first block matching
|
||||
|
@ -202,6 +207,7 @@ private:
|
|||
RefPtr<WheelBlockState> mActiveWheelBlock;
|
||||
RefPtr<DragBlockState> mActiveDragBlock;
|
||||
RefPtr<PanGestureBlockState> mActivePanGestureBlock;
|
||||
RefPtr<KeyboardBlockState> mActiveKeyboardBlock;
|
||||
|
||||
// The APZC to which the last event was delivered
|
||||
RefPtr<AsyncPanZoomController> mLastActiveApzc;
|
||||
|
|
|
@ -38,6 +38,12 @@ QueuedInput::QueuedInput(const PanGestureInput& aInput, PanGestureBlockState& aB
|
|||
{
|
||||
}
|
||||
|
||||
QueuedInput::QueuedInput(const KeyboardInput& aInput, KeyboardBlockState& aBlock)
|
||||
: mInput(MakeUnique<KeyboardInput>(aInput))
|
||||
, mBlock(&aBlock)
|
||||
{
|
||||
}
|
||||
|
||||
InputData*
|
||||
QueuedInput::Input()
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@ class MultiTouchInput;
|
|||
class ScrollWheelInput;
|
||||
class MouseInput;
|
||||
class PanGestureInput;
|
||||
class KeyboardInput;
|
||||
|
||||
namespace layers {
|
||||
|
||||
|
@ -25,6 +26,7 @@ class TouchBlockState;
|
|||
class WheelBlockState;
|
||||
class DragBlockState;
|
||||
class PanGestureBlockState;
|
||||
class KeyboardBlockState;
|
||||
|
||||
/**
|
||||
* This lightweight class holds a pointer to an input event that has not yet
|
||||
|
@ -38,6 +40,7 @@ public:
|
|||
QueuedInput(const ScrollWheelInput& aInput, WheelBlockState& aBlock);
|
||||
QueuedInput(const MouseInput& aInput, DragBlockState& aBlock);
|
||||
QueuedInput(const PanGestureInput& aInput, PanGestureBlockState& aBlock);
|
||||
QueuedInput(const KeyboardInput& aInput, KeyboardBlockState& aBlock);
|
||||
|
||||
InputData* Input();
|
||||
InputBlockState* Block();
|
||||
|
|
|
@ -119,6 +119,20 @@ APZCTreeManagerChild::ReceiveInputEvent(
|
|||
event = processedEvent;
|
||||
return res;
|
||||
}
|
||||
case KEYBOARD_INPUT: {
|
||||
KeyboardInput& event = aEvent.AsKeyboardInput();
|
||||
KeyboardInput processedEvent;
|
||||
|
||||
nsEventStatus res;
|
||||
SendReceiveKeyboardInputEvent(event,
|
||||
&res,
|
||||
&processedEvent,
|
||||
aOutTargetGuid,
|
||||
aOutInputBlockId);
|
||||
|
||||
event = processedEvent;
|
||||
return res;
|
||||
}
|
||||
default: {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid InputData type.");
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
|
|
|
@ -144,6 +144,25 @@ APZCTreeManagerParent::RecvReceiveScrollWheelInputEvent(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
APZCTreeManagerParent::RecvReceiveKeyboardInputEvent(
|
||||
const KeyboardInput& aEvent,
|
||||
nsEventStatus* aOutStatus,
|
||||
KeyboardInput* aOutEvent,
|
||||
ScrollableLayerGuid* aOutTargetGuid,
|
||||
uint64_t* aOutInputBlockId)
|
||||
{
|
||||
KeyboardInput event = aEvent;
|
||||
|
||||
*aOutStatus = mTreeManager->ReceiveInputEvent(
|
||||
event,
|
||||
aOutTargetGuid,
|
||||
aOutInputBlockId);
|
||||
*aOutEvent = event;
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
APZCTreeManagerParent::RecvSetKeyboardMap(const KeyboardMap& aKeyboardMap)
|
||||
{
|
||||
|
|
|
@ -78,6 +78,14 @@ public:
|
|||
ScrollableLayerGuid* aOutTargetGuid,
|
||||
uint64_t* aOutInputBlockId) override;
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RecvReceiveKeyboardInputEvent(
|
||||
const KeyboardInput& aEvent,
|
||||
nsEventStatus* aOutStatus,
|
||||
KeyboardInput* aOutEvent,
|
||||
ScrollableLayerGuid* aOutTargetGuid,
|
||||
uint64_t* aOutInputBlockId) override;
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RecvSetKeyboardMap(const KeyboardMap& aKeyboardMap) override;
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ using class mozilla::PinchGestureInput from "InputData.h";
|
|||
using mozilla::PinchGestureInput::PinchGestureType from "InputData.h";
|
||||
using class mozilla::TapGestureInput from "InputData.h";
|
||||
using class mozilla::ScrollWheelInput from "InputData.h";
|
||||
using class mozilla::KeyboardInput from "InputData.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -121,6 +122,12 @@ parent:
|
|||
ScrollableLayerGuid aOutTargetGuid,
|
||||
uint64_t aOutInputBlockId);
|
||||
|
||||
sync ReceiveKeyboardInputEvent(KeyboardInput aEvent)
|
||||
returns (nsEventStatus aOutStatus,
|
||||
KeyboardInput aOutEvent,
|
||||
ScrollableLayerGuid aOutTargetGuid,
|
||||
uint64_t aOutInputBlockId);
|
||||
|
||||
async UpdateWheelTransaction(LayoutDeviceIntPoint aRefPoint, EventMessage aEventMessage);
|
||||
|
||||
sync ProcessUnhandledEvent(LayoutDeviceIntPoint aRefPoint)
|
||||
|
|
|
@ -279,6 +279,8 @@ private:
|
|||
// We will keep these in an alphabetical order to make it easier to see if
|
||||
// a method accessing a pref already exists. Just add yours in the list.
|
||||
|
||||
DECL_GFX_PREF(Live, "accessibility.browsewithcaret", AccessibilityBrowseWithCaret, bool, false);
|
||||
|
||||
// The apz prefs are explained in AsyncPanZoomController.cpp
|
||||
DECL_GFX_PREF(Live, "apz.allow_checkerboarding", APZAllowCheckerboarding, bool, true);
|
||||
DECL_GFX_PREF(Live, "apz.allow_immediate_handoff", APZAllowImmediateHandoff, bool, true);
|
||||
|
@ -310,6 +312,7 @@ private:
|
|||
DECL_GFX_PREF(Live, "apz.fling_stop_on_tap_threshold", APZFlingStopOnTapThreshold, float, 0.05f);
|
||||
DECL_GFX_PREF(Live, "apz.fling_stopped_threshold", APZFlingStoppedThreshold, float, 0.01f);
|
||||
DECL_GFX_PREF(Live, "apz.highlight_checkerboarded_areas", APZHighlightCheckerboardedAreas, bool, false);
|
||||
DECL_GFX_PREF(Once, "apz.keyboard.enabled", APZKeyboardEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.max_velocity_inches_per_ms", APZMaxVelocity, float, -1.0f);
|
||||
DECL_GFX_PREF(Once, "apz.max_velocity_queue_size", APZMaxVelocityQueueSize, uint32_t, 5);
|
||||
DECL_GFX_PREF(Live, "apz.min_skate_speed", APZMinSkateSpeed, float, 1.0f);
|
||||
|
|
|
@ -969,6 +969,8 @@ description =
|
|||
description =
|
||||
[PAPZCTreeManager::ProcessUnhandledEvent]
|
||||
description =
|
||||
[PAPZCTreeManager::ReceiveKeyboardInputEvent]
|
||||
description =
|
||||
[PCompositorBridge::Initialize]
|
||||
description =
|
||||
[PCompositorBridge::GetFrameUniformity]
|
||||
|
|
|
@ -701,6 +701,7 @@ pref("apz.fling_min_velocity_threshold", "0.5");
|
|||
pref("apz.fling_stop_on_tap_threshold", "0.05");
|
||||
pref("apz.fling_stopped_threshold", "0.01");
|
||||
pref("apz.highlight_checkerboarded_areas", false);
|
||||
pref("apz.keyboard.enabled", false);
|
||||
pref("apz.max_velocity_inches_per_ms", "-1.0");
|
||||
pref("apz.max_velocity_queue_size", 5);
|
||||
pref("apz.min_skate_speed", "1.0");
|
||||
|
|
Загрузка…
Ссылка в новой задаче