summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-03 08:41:45 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-03 08:41:45 +0000
commit2c988d7a5f25a0d6b4b84baf4d1e6e0396be0e54 (patch)
tree6b1188a62ce9c2ddf29f5ee6a2088c0e6b95b2f4
parent117cc7b676245fe450bebcc32f5f87c4dc4ef48a (diff)
downloadchromium_src-2c988d7a5f25a0d6b4b84baf4d1e6e0396be0e54.zip
chromium_src-2c988d7a5f25a0d6b4b84baf4d1e6e0396be0e54.tar.gz
chromium_src-2c988d7a5f25a0d6b4b84baf4d1e6e0396be0e54.tar.bz2
Ignore key events that has non standard state mask when detecting key repeat
BUG=385873 Review URL: https://codereview.chromium.org/358693006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281223 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/events/event.cc22
-rw-r--r--ui/events/event_unittest.cc37
-rw-r--r--ui/views/controls/textfield/textfield.cc9
3 files changed, 52 insertions, 16 deletions
diff --git a/ui/events/event.cc b/ui/events/event.cc
index e562672..7dc7fb1 100644
--- a/ui/events/event.cc
+++ b/ui/events/event.cc
@@ -86,10 +86,22 @@ std::string EventTypeName(ui::EventType type) {
bool IsX11SendEventTrue(const base::NativeEvent& event) {
#if defined(USE_X11)
- if (event && event->xany.send_event)
- return true;
+ return event && event->xany.send_event;
+#else
+ return false;
#endif
+}
+
+bool X11EventHasNonStandardState(const base::NativeEvent& event) {
+#if defined(USE_X11)
+ const unsigned int kAllStateMask =
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask |
+ Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask |
+ LockMask | ControlMask | AnyModifier;
+ return event && (event->xkey.state & ~kAllStateMask) != 0;
+#else
return false;
+#endif
}
} // namespace
@@ -497,7 +509,11 @@ bool KeyEvent::IsRepeated(const KeyEvent& event) {
// A safe guard in case if there were continous key pressed events that are
// not auto repeat.
const int kMaxAutoRepeatTimeMs = 2000;
-
+ // Ignore key events that have non standard state masks as it may be
+ // reposted by an IME. IBUS-GTK uses this field to detect the
+ // re-posted event for example. crbug.com/385873.
+ if (X11EventHasNonStandardState(event.native_event()))
+ return false;
if (event.is_char())
return false;
if (event.type() == ui::ET_KEY_RELEASED) {
diff --git a/ui/events/event_unittest.cc b/ui/events/event_unittest.cc
index 40bfa96..5a5742d 100644
--- a/ui/events/event_unittest.cc
+++ b/ui/events/event_unittest.cc
@@ -344,6 +344,12 @@ TEST(EventTest, AutoRepeat) {
native_event_a_released.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, kNativeCodeA);
ScopedXI2Event native_event_b_pressed;
native_event_b_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_B, kNativeCodeB);
+ ScopedXI2Event native_event_a_pressed_nonstandard_state;
+ native_event_a_pressed_nonstandard_state.InitKeyEvent(
+ ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
+ // IBUS-GTK uses the mask (1 << 25) to detect reposted event.
+ static_cast<XEvent*>(native_event_a_pressed_nonstandard_state)->xkey.state |=
+ 1 << 25;
#elif defined(OS_WIN)
const LPARAM lParam_a = GetLParamFromScanCode(kNativeCodeA);
const LPARAM lParam_b = GetLParamFromScanCode(kNativeCodeB);
@@ -352,29 +358,38 @@ TEST(EventTest, AutoRepeat) {
MSG native_event_b_pressed = { NULL, WM_KEYUP, VKEY_B, lParam_b };
#endif
KeyEvent key_a1(native_event_a_pressed, false);
- DCHECK(!key_a1.IsRepeat());
+ EXPECT_FALSE(key_a1.IsRepeat());
KeyEvent key_a1_released(native_event_a_released, false);
- DCHECK(!key_a1_released.IsRepeat());
+ EXPECT_FALSE(key_a1_released.IsRepeat());
KeyEvent key_a2(native_event_a_pressed, false);
- DCHECK(!key_a2.IsRepeat());
+ EXPECT_FALSE(key_a2.IsRepeat());
KeyEvent key_a2_repeated(native_event_a_pressed, false);
- DCHECK(key_a2_repeated.IsRepeat());
+ EXPECT_TRUE(key_a2_repeated.IsRepeat());
KeyEvent key_a2_released(native_event_a_released, false);
- DCHECK(!key_a2_released.IsRepeat());
+ EXPECT_FALSE(key_a2_released.IsRepeat());
KeyEvent key_a3(native_event_a_pressed, false);
- DCHECK(!key_a3.IsRepeat());
+ EXPECT_FALSE(key_a3.IsRepeat());
KeyEvent key_b(native_event_b_pressed, false);
- DCHECK(!key_b.IsRepeat());
+ EXPECT_FALSE(key_b.IsRepeat());
KeyEvent key_a3_again(native_event_a_pressed, false);
- DCHECK(!key_a3_again.IsRepeat());
+ EXPECT_FALSE(key_a3_again.IsRepeat());
KeyEvent key_a3_repeated(native_event_a_pressed, false);
- DCHECK(key_a3_repeated.IsRepeat());
+ EXPECT_TRUE(key_a3_repeated.IsRepeat());
KeyEvent key_a3_repeated2(native_event_a_pressed, false);
- DCHECK(key_a3_repeated2.IsRepeat());
+ EXPECT_TRUE(key_a3_repeated2.IsRepeat());
KeyEvent key_a3_released(native_event_a_released, false);
- DCHECK(!key_a3_released.IsRepeat());
+ EXPECT_FALSE(key_a3_released.IsRepeat());
+
+#if defined(USE_X11)
+ KeyEvent key_a4_pressed(native_event_a_pressed, false);
+ EXPECT_FALSE(key_a4_pressed.IsRepeat());
+
+ KeyEvent key_a4_pressed_nonstandard_state(
+ native_event_a_pressed_nonstandard_state, false);
+ EXPECT_FALSE(key_a4_pressed_nonstandard_state.IsRepeat());
+#endif
}
#endif // USE_X11 || OS_WIN
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index cb3e542..f28f8f2 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -1314,12 +1314,17 @@ void Textfield::InsertText(const base::string16& new_text) {
}
void Textfield::InsertChar(base::char16 ch, int flags) {
+ const int kControlModifierMask = ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
+ ui::EF_COMMAND_DOWN | ui::EF_ALTGR_DOWN |
+ ui::EF_MOD3_DOWN;
+
// Filter out all control characters, including tab and new line characters,
// and all characters with Alt modifier. But allow characters with the AltGr
// modifier. On Windows AltGr is represented by Alt+Ctrl, and on Linux it's a
// different flag that we don't care about.
- const bool should_insert_char = ((ch >= 0x20 && ch < 0x7F) || ch > 0x9F) &&
- (flags & ~(ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN)) != ui::EF_ALT_DOWN;
+ const bool should_insert_char =
+ ((ch >= 0x20 && ch < 0x7F) || ch > 0x9F) &&
+ (flags & kControlModifierMask) != ui::EF_ALT_DOWN;
if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || !should_insert_char)
return;