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
--- 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
@@ -410,16 +412,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
@@ -95,16 +95,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',
@@ -276,16 +277,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',