Bug 1351783 part 3 - Add a KeyboardScrollAction type. r=kats,masayuki
authorRyan Hunt <rhunt@eqrion.net>
Mon, 05 Jun 2017 18:17:30 -0500
changeset 402065 b95f62f11e87a75a26cf6bc1893f406f697650f9
parent 402064 887a8e96eeda59abc75f273304314a5a42414ea9
child 402066 2f051c7a8b086b903198c85bec7defb01349433e
push idunknown
push userunknown
push dateunknown
reviewerskats, masayuki
bugs1351783
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
dom/base/nsGlobalWindowCommands.cpp
dom/base/nsGlobalWindowCommands.h
gfx/layers/apz/src/Keyboard.cpp
gfx/layers/apz/src/Keyboard.h
gfx/layers/ipc/LayersMessageUtils.h
gfx/layers/moz.build
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -31,21 +31,23 @@
 #include "nsIClipboard.h"
 #include "ContentEventHandler.h"
 #include "nsContentUtils.h"
 #include "nsIWordBreaker.h"
 #include "mozilla/Attributes.h"
 #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";
 constexpr const char * sCopyImageLocationString = "cmd_copyImageLocation";
 constexpr const char * sCopyImageContentsString = "cmd_copyImageContents";
 constexpr const char * sCopyImageString = "cmd_copyImage";
 
 constexpr const char * sScrollTopString = "cmd_scrollTop";
@@ -266,43 +268,54 @@ IsCaretOnInWindow(nsPIDOMWindowOuter* aW
       }
     }
   }
   return caretOn;
 }
 
 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 }
 };
 
 nsresult
 nsSelectMoveScrollCommand::DoCommand(const char *aCommandName, nsISupports *aCommandContext)
 {
   nsCOMPtr<nsPIDOMWindowOuter> piWindow(do_QueryInterface(aCommandContext));
@@ -329,33 +342,42 @@ nsSelectMoveScrollCommand::DoCommand(con
 
 // XXX It's not clear to me yet how we should handle the "scroll" option
 // for these commands; for now, I'm mapping them back to ScrollCharacter,
 // ScrollLine, etc., as if for horizontal-mode content, but this may need
 // to be reconsidered once we have more experience with vertical content.
 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 },
 };
 
 nsresult
 nsPhysicalSelectMoveScrollCommand::DoCommand(const char *aCommandName,
                                              nsISupports *aCommandContext)
 {
   nsCOMPtr<nsPIDOMWindowOuter> piWindow(do_QueryInterface(aCommandContext));
@@ -1257,8 +1279,41 @@ nsWindowCommandRegistration::RegisterWin
 #endif
 
   NS_REGISTER_ONE_COMMAND(nsClipboardDragDropHookCommand, "cmd_clipboardDragDropHook");
 
   NS_REGISTER_ONE_COMMAND(nsLookUpDictionaryCommand, "cmd_lookUpDictionary");
 
   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;
+}
--- a/dom/base/nsGlobalWindowCommands.h
+++ b/dom/base/nsGlobalWindowCommands.h
@@ -4,24 +4,46 @@
  * 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 nsGlobalWindowCommands_h__
 #define nsGlobalWindowCommands_h__
 
 #include "nscore.h"
 
+namespace mozilla {
+namespace layers {
+struct KeyboardScrollAction;
+} // namespace layers
+} // namespace mozilla
+
 class nsIControllerCommandTable;
 
 class nsWindowCommandRegistration
 {
 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        \
  { /* 7BD05C78-6A26-11D7-B16F-0003938A9D96 */       \
   0x7BD05C78, 0x6A26, 0x11D7, {0xB1, 0x6F, 0x00, 0x03, 0x93, 0x8A, 0x9D, 0x96} }
 
 #define NS_WINDOWCONTROLLER_CONTRACTID "@mozilla.org/dom/window-controller;1"
 
new file mode 100644
--- /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
new file mode 100644
--- /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
--- a/gfx/layers/ipc/LayersMessageUtils.h
+++ b/gfx/layers/ipc/LayersMessageUtils.h
@@ -7,21 +7,23 @@
 #ifndef mozilla_layers_LayersMessageUtils
 #define mozilla_layers_LayersMessageUtils
 
 #include "FrameMetrics.h"
 #include "base/process_util.h"
 #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"
 
 #include <stdint.h>
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4800 )
 #endif
@@ -412,16 +414,42 @@ struct ParamTraits<mozilla::layers::Even
     return (ReadParam(aMsg, aIter, &aResult->mHitRegion) &&
             ReadParam(aMsg, aIter, &aResult->mDispatchToContentHitRegion) &&
             ReadParam(aMsg, aIter, &aResult->mNoActionRegion) &&
             ReadParam(aMsg, aIter, &aResult->mHorizontalPanRegion) &&
             ReadParam(aMsg, aIter, &aResult->mVerticalPanRegion));
   }
 };
 
+template <>
+struct ParamTraits<mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType>
+  : public ContiguousEnumSerializer<
+             mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType,
+             mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType::eScrollCharacter,
+             mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType::eSentinel>
+{};
+
+template <>
+struct ParamTraits<mozilla::layers::KeyboardScrollAction>
+{
+  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 <>
 struct ParamTraits<TapType>
   : public ContiguousEnumSerializer<
              TapType,
              TapType::eSingleTap,
              TapType::eSentinel>
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -97,16 +97,17 @@ EXPORTS.mozilla.layers += [
     'apz/public/IAPZCTreeManager.h',
     'apz/public/MetricsSharingController.h',
     # exporting things from apz/src is temporary until we extract a
     # proper interface for the code there
     'apz/src/APZCTreeManager.h',
     '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',
     'apz/util/APZCCallbackHelper.h',
     'apz/util/APZEventState.h',
     'apz/util/APZThreadUtils.h',
     'apz/util/ChromeProcessController.h',
     'apz/util/ContentProcessController.h',
@@ -286,16 +287,17 @@ UNIFIED_SOURCES += [
     'apz/src/AsyncPanZoomController.cpp',
     'apz/src/Axis.cpp',
     'apz/src/CheckerboardEvent.cpp',
     'apz/src/DragTracker.cpp',
     'apz/src/GestureEventListener.cpp',
     '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',
     'apz/src/TouchCounter.cpp',
     'apz/src/WheelScrollAnimation.cpp',
     'apz/testutil/APZTestData.cpp',
     'apz/util/ActiveElementManager.cpp',
     'apz/util/APZCCallbackHelper.cpp',