From a97d402536bc8774814938f54aaf74cb31f83ece Mon Sep 17 00:00:00 2001 From: Ryan Hunt Date: Mon, 5 Jun 2017 18:17:30 -0500 Subject: [PATCH] Bug 1351783 part 3 - Add a KeyboardScrollAction type. r=kats,masayuki The different types of keyboard scrolls are represented as command strings that are dispatched to nsGlobalWindowCommands. This commit adds a class to represent these command strings, along with a function to find the keyboard scroll action corresponding to a command string. MozReview-Commit-ID: 20vvYdzlYYT --HG-- extra : rebase_source : 8a965429f57534ac65da597cbb05a08284f7eaeb --- dom/base/nsGlobalWindowCommands.cpp | 55 +++++++++++++++++++++++++++++ dom/base/nsGlobalWindowCommands.h | 22 ++++++++++++ gfx/layers/apz/src/Keyboard.cpp | 42 ++++++++++++++++++++++ gfx/layers/apz/src/Keyboard.h | 46 ++++++++++++++++++++++++ gfx/layers/ipc/LayersMessageUtils.h | 28 +++++++++++++++ gfx/layers/moz.build | 2 ++ 6 files changed, 195 insertions(+) create mode 100644 gfx/layers/apz/src/Keyboard.cpp create mode 100644 gfx/layers/apz/src/Keyboard.h diff --git a/dom/base/nsGlobalWindowCommands.cpp b/dom/base/nsGlobalWindowCommands.cpp index 267cf3da0e20..c6bd89c3ce1e 100644 --- a/dom/base/nsGlobalWindowCommands.cpp +++ b/dom/base/nsGlobalWindowCommands.cpp @@ -36,11 +36,13 @@ #include "mozilla/BasicEvents.h" #include "mozilla/TextEvents.h" #include "mozilla/dom/Selection.h" +#include "mozilla/layers/Keyboard.h" #include "nsIClipboardDragDropHooks.h" #include "nsIClipboardDragDropHookList.h" using namespace mozilla; +using namespace mozilla::layers; constexpr const char * sSelectAllString = "cmd_selectAll"; constexpr const char * sSelectNoneString = "cmd_selectNone"; @@ -271,33 +273,44 @@ IsCaretOnInWindow(nsPIDOMWindowOuter* aWindow, nsISelectionController* aSelCont) static constexpr struct BrowseCommand { const char *reverse, *forward; + KeyboardScrollAction::KeyboardScrollActionType scrollAction; nsresult (NS_STDCALL nsISelectionController::*scroll)(bool); nsresult (NS_STDCALL nsISelectionController::*move)(bool, bool); } browseCommands[] = { { sScrollTopString, sScrollBottomString, + KeyboardScrollAction::eScrollComplete, &nsISelectionController::CompleteScroll }, { sScrollPageUpString, sScrollPageDownString, + KeyboardScrollAction::eScrollPage, &nsISelectionController::ScrollPage }, { sScrollLineUpString, sScrollLineDownString, + KeyboardScrollAction::eScrollLine, &nsISelectionController::ScrollLine }, { sScrollLeftString, sScrollRightString, + KeyboardScrollAction::eScrollCharacter, &nsISelectionController::ScrollCharacter }, { sMoveTopString, sMoveBottomString, + KeyboardScrollAction::eScrollComplete, &nsISelectionController::CompleteScroll, &nsISelectionController::CompleteMove }, { sMovePageUpString, sMovePageDownString, + KeyboardScrollAction::eScrollPage, &nsISelectionController::ScrollPage, &nsISelectionController::PageMove }, { sLinePreviousString, sLineNextString, + KeyboardScrollAction::eScrollLine, &nsISelectionController::ScrollLine, &nsISelectionController::LineMove }, { sWordPreviousString, sWordNextString, + KeyboardScrollAction::eScrollCharacter, &nsISelectionController::ScrollCharacter, &nsISelectionController::WordMove }, { sCharPreviousString, sCharNextString, + KeyboardScrollAction::eScrollCharacter, &nsISelectionController::ScrollCharacter, &nsISelectionController::CharacterMove }, { sBeginLineString, sEndLineString, + KeyboardScrollAction::eScrollComplete, &nsISelectionController::CompleteScroll, &nsISelectionController::IntraLineMove } }; @@ -334,23 +347,32 @@ nsSelectMoveScrollCommand::DoCommand(const char *aCommandName, nsISupports *aCom static const struct PhysicalBrowseCommand { const char *command; int16_t direction, amount; + KeyboardScrollAction::KeyboardScrollActionType scrollAction; nsresult (NS_STDCALL nsISelectionController::*scroll)(bool); } physicalBrowseCommands[] = { { sMoveLeftString, nsISelectionController::MOVE_LEFT, 0, + KeyboardScrollAction::eScrollCharacter, &nsISelectionController::ScrollCharacter }, { sMoveRightString, nsISelectionController::MOVE_RIGHT, 0, + KeyboardScrollAction::eScrollCharacter, &nsISelectionController::ScrollCharacter }, { sMoveUpString, nsISelectionController::MOVE_UP, 0, + KeyboardScrollAction::eScrollLine, &nsISelectionController::ScrollLine }, { sMoveDownString, nsISelectionController::MOVE_DOWN, 0, + KeyboardScrollAction::eScrollLine, &nsISelectionController::ScrollLine }, { sMoveLeft2String, nsISelectionController::MOVE_LEFT, 1, + KeyboardScrollAction::eScrollCharacter, &nsISelectionController::ScrollCharacter }, { sMoveRight2String, nsISelectionController::MOVE_RIGHT, 1, + KeyboardScrollAction::eScrollCharacter, &nsISelectionController::ScrollCharacter }, { sMoveUp2String, nsISelectionController::MOVE_UP, 1, + KeyboardScrollAction::eScrollComplete, &nsISelectionController::CompleteScroll }, { sMoveDown2String, nsISelectionController::MOVE_DOWN, 1, + KeyboardScrollAction::eScrollComplete, &nsISelectionController::CompleteScroll }, }; @@ -1262,3 +1284,36 @@ nsWindowCommandRegistration::RegisterWindowCommands( return rv; } + +/* static */ bool +nsGlobalWindowCommands::FindScrollCommand(const char* aCommandName, + KeyboardScrollAction* aOutAction) +{ + // Search for a keyboard scroll action to do for this command in browseCommands + // and physicalBrowseCommands. Each command exists in only one of them, so the + // order we examine browseCommands and physicalBrowseCommands doesn't matter. + + for (size_t i = 0; i < ArrayLength(browseCommands); i++) { + const BrowseCommand& cmd = browseCommands[i]; + bool forward = !strcmp(aCommandName, cmd.forward); + bool reverse = !strcmp(aCommandName, cmd.reverse); + if (forward || reverse) { + *aOutAction = KeyboardScrollAction(cmd.scrollAction, forward); + return true; + } + } + + for (size_t i = 0; i < ArrayLength(physicalBrowseCommands); i++) { + const PhysicalBrowseCommand& cmd = physicalBrowseCommands[i]; + if (!strcmp(aCommandName, cmd.command)) { + int16_t dir = cmd.direction; + bool forward = (dir == nsISelectionController::MOVE_RIGHT || + dir == nsISelectionController::MOVE_DOWN); + + *aOutAction = KeyboardScrollAction(cmd.scrollAction, forward); + return true; + } + } + + return false; +} diff --git a/dom/base/nsGlobalWindowCommands.h b/dom/base/nsGlobalWindowCommands.h index 3508af8fba9a..2f1126f78f02 100644 --- a/dom/base/nsGlobalWindowCommands.h +++ b/dom/base/nsGlobalWindowCommands.h @@ -9,6 +9,12 @@ #include "nscore.h" +namespace mozilla { +namespace layers { +struct KeyboardScrollAction; +} // namespace layers +} // namespace mozilla + class nsIControllerCommandTable; class nsWindowCommandRegistration @@ -17,6 +23,22 @@ public: static nsresult RegisterWindowCommands(nsIControllerCommandTable *ccm); }; +class nsGlobalWindowCommands +{ +public: + typedef mozilla::layers::KeyboardScrollAction KeyboardScrollAction; + + /** + * Search through nsGlobalWindowCommands to find the keyboard scrolling action + * that would be done in response to a command. + * + * @param aCommandName the name of the command + * @param aOutAction the result of searching for this command, must not be null + * @returns whether a keyboard action was found or not + */ + static bool FindScrollCommand(const char* aCommandName, + KeyboardScrollAction* aOutAction); +}; // XXX find a better home for these #define NS_WINDOWCONTROLLER_CID \ diff --git a/gfx/layers/apz/src/Keyboard.cpp b/gfx/layers/apz/src/Keyboard.cpp new file mode 100644 index 000000000000..dde0832be3b4 --- /dev/null +++ b/gfx/layers/apz/src/Keyboard.cpp @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/Keyboard.h" + +namespace mozilla { +namespace layers { + +/* static */ nsIScrollableFrame::ScrollUnit +KeyboardScrollAction::GetScrollUnit(KeyboardScrollAction::KeyboardScrollActionType aDeltaType) +{ + switch (aDeltaType) { + case KeyboardScrollAction::eScrollCharacter: + return nsIScrollableFrame::LINES; + case KeyboardScrollAction::eScrollLine: + return nsIScrollableFrame::LINES; + case KeyboardScrollAction::eScrollPage: + return nsIScrollableFrame::PAGES; + case KeyboardScrollAction::eScrollComplete: + return nsIScrollableFrame::WHOLE; + case KeyboardScrollAction::eSentinel: + MOZ_ASSERT_UNREACHABLE("Invalid KeyboardScrollActionType."); + return nsIScrollableFrame::WHOLE; + } +} + +KeyboardScrollAction::KeyboardScrollAction() + : mType(KeyboardScrollAction::eScrollCharacter) + , mForward(false) +{ +} + +KeyboardScrollAction::KeyboardScrollAction(KeyboardScrollActionType aType, bool aForward) + : mType(aType) + , mForward(aForward) +{ +} + +} // namespace layers +} // namespace mozilla diff --git a/gfx/layers/apz/src/Keyboard.h b/gfx/layers/apz/src/Keyboard.h new file mode 100644 index 000000000000..7ca39271736e --- /dev/null +++ b/gfx/layers/apz/src/Keyboard.h @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef mozilla_layers_Keyboard_h +#define mozilla_layers_Keyboard_h + +#include "nsIScrollableFrame.h" // for nsIScrollableFrame::ScrollUnit + +namespace mozilla { +namespace layers { + +/** + * This class represents a scrolling action to be performed on a scrollable layer. + */ +struct KeyboardScrollAction final +{ +public: + enum KeyboardScrollActionType : uint8_t + { + eScrollCharacter, + eScrollLine, + eScrollPage, + eScrollComplete, + + // Used as an upper bound for ContiguousEnumSerializer + eSentinel, + }; + + static nsIScrollableFrame::ScrollUnit + GetScrollUnit(KeyboardScrollActionType aDeltaType); + + KeyboardScrollAction(); + KeyboardScrollAction(KeyboardScrollActionType aType, bool aForward); + + // The type of scroll to perform for this action + KeyboardScrollActionType mType; + // Whether to scroll forward or backward along the axis of this action type + bool mForward; +}; + +} // namespace layers +} // namespace mozilla + +#endif // mozilla_layers_Keyboard_h diff --git a/gfx/layers/ipc/LayersMessageUtils.h b/gfx/layers/ipc/LayersMessageUtils.h index 81bc9b9a3204..b74f920ed2ea 100644 --- a/gfx/layers/ipc/LayersMessageUtils.h +++ b/gfx/layers/ipc/LayersMessageUtils.h @@ -12,11 +12,13 @@ #include "chrome/common/ipc_message_utils.h" #include "gfxTelemetry.h" #include "ipc/IPCMessageUtils.h" +#include "ipc/nsGUIEventIPC.h" #include "mozilla/GfxMessageUtils.h" #include "mozilla/layers/AsyncDragMetrics.h" #include "mozilla/layers/CompositorOptions.h" #include "mozilla/layers/CompositorTypes.h" #include "mozilla/layers/GeckoContentController.h" +#include "mozilla/layers/Keyboard.h" #include "mozilla/layers/LayerAttributes.h" #include "mozilla/layers/LayersTypes.h" @@ -417,6 +419,32 @@ struct ParamTraits } }; +template <> +struct ParamTraits + : public ContiguousEnumSerializer< + mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType, + mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType::eScrollCharacter, + mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType::eSentinel> +{}; + +template <> +struct ParamTraits +{ + typedef mozilla::layers::KeyboardScrollAction paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mType); + WriteParam(aMsg, aParam.mForward); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, &aResult->mType) && + ReadParam(aMsg, aIter, &aResult->mForward); + } +}; + typedef mozilla::layers::GeckoContentController::TapType TapType; template <> diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 3ae0bcb745a7..dbdfb2ef8a42 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -102,6 +102,7 @@ EXPORTS.mozilla.layers += [ 'apz/src/APZUtils.h', 'apz/src/AsyncDragMetrics.h', 'apz/src/AsyncPanZoomAnimation.h', + 'apz/src/Keyboard.h', 'apz/src/TouchCounter.h', 'apz/testutil/APZTestData.h', 'apz/util/ActiveElementManager.h', @@ -291,6 +292,7 @@ UNIFIED_SOURCES += [ 'apz/src/HitTestingTreeNode.cpp', 'apz/src/InputBlockState.cpp', 'apz/src/InputQueue.cpp', + 'apz/src/Keyboard.cpp', 'apz/src/OverscrollHandoffState.cpp', 'apz/src/PotentialCheckerboardDurationTracker.cpp', 'apz/src/QueuedInput.cpp',