diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-03 08:41:45 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-03 08:41:45 +0000 |
commit | 2c988d7a5f25a0d6b4b84baf4d1e6e0396be0e54 (patch) | |
tree | 6b1188a62ce9c2ddf29f5ee6a2088c0e6b95b2f4 | |
parent | 117cc7b676245fe450bebcc32f5f87c4dc4ef48a (diff) | |
download | chromium_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.cc | 22 | ||||
-rw-r--r-- | ui/events/event_unittest.cc | 37 | ||||
-rw-r--r-- | ui/views/controls/textfield/textfield.cc | 9 |
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; |