Don't count modifiers-changed events as being user gestures.

BUG=709765
TEST=as in bug

Review-Url: https://codereview.chromium.org/2874263002
Cr-Commit-Position: refs/heads/master@{#472876}
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 66ce63b..94eaffa8 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -832,6 +832,11 @@
       ui::KeycodeConverter::KeyStringToDomKey(key_string.Utf8()));
 }
 
+bool BlinkPlatformImpl::IsDomKeyForModifier(int dom_key) {
+  return ui::KeycodeConverter::IsDomKeyForModifier(
+      static_cast<ui::DomKey>(dom_key));
+}
+
 std::unique_ptr<blink::WebFeaturePolicy> BlinkPlatformImpl::CreateFeaturePolicy(
     const blink::WebFeaturePolicy* parent_policy,
     const blink::WebParsedFeaturePolicy& container_policy,
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index 620e63e..e43acb5 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -115,6 +115,7 @@
   int DomEnumFromCodeString(const blink::WebString& codeString) override;
   blink::WebString DomKeyStringFromEnum(int dom_key) override;
   int DomKeyEnumFromString(const blink::WebString& key_string) override;
+  bool IsDomKeyForModifier(int dom_key) override;
 
   // This class does *not* own the compositor thread. It is the responsibility
   // of the caller to ensure that the compositor thread is cleared before it is
diff --git a/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp b/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp
index d055843..396bbd6 100644
--- a/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp
@@ -4,6 +4,8 @@
 
 #include "KeyboardEventManager.h"
 
+#include <memory>
+
 #include "core/dom/DocumentUserGestureToken.h"
 #include "core/dom/Element.h"
 #include "core/editing/Editor.h"
@@ -23,6 +25,7 @@
 #include "platform/KeyboardCodes.h"
 #include "platform/UserGestureIndicator.h"
 #include "platform/WindowsKeyboardCodes.h"
+#include "public/platform/Platform.h"
 #include "public/platform/WebInputEvent.h"
 
 #if OS(WIN)
@@ -187,8 +190,17 @@
   if (!node)
     return WebInputEventResult::kNotHandled;
 
-  UserGestureIndicator gesture_indicator(
-      DocumentUserGestureToken::Create(frame_->GetDocument()));
+  // To be meaningful enough to indicate user intention, a keyboard event needs
+  // - not to be a modifier event
+  // https://crbug.com/709765
+  bool is_modifier =
+      Platform::Current()->IsDomKeyForModifier(initial_key_event.dom_key);
+
+  std::unique_ptr<UserGestureIndicator> gesture_indicator;
+  if (!is_modifier) {
+    gesture_indicator.reset(new UserGestureIndicator(
+        DocumentUserGestureToken::Create(frame_->GetDocument())));
+  }
 
   // In IE, access keys are special, they are handled after default keydown
   // processing, but cannot be canceled - this is hard to match.  On Mac OS X,
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index 86c66e5b..f7360bf6 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -626,6 +626,11 @@
   // Returns 0 if DOM key enum is not found.
   virtual int DomKeyEnumFromString(const WebString& key_string) { return 0; }
 
+  // This method returns whether the specified |domKey| is a modifier key.
+  // |domKey| values are based on the value defined in
+  // ui/events/keycodes/dom3/dom_key_data.h.
+  virtual bool IsDomKeyForModifier(int dom_key) { return false; }
+
   // Quota -----------------------------------------------------------
 
   // Queries the storage partition's storage usage and quota information.