summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/events/x/events_x.cc7
-rw-r--r--ui/events/x/events_x_unittest.cc33
2 files changed, 37 insertions, 3 deletions
diff --git a/ui/events/x/events_x.cc b/ui/events/x/events_x.cc
index 58f9fed..bd12bd8 100644
--- a/ui/events/x/events_x.cc
+++ b/ui/events/x/events_x.cc
@@ -162,12 +162,15 @@ int GetEventFlagsFromXKeyEvent(XEvent* xevent) {
// For example, when a user hits XK_Multi_key, XK_apostrophe, and XK_e in
// order to input "é", then XIM generates a key event with keycode=0 and
// state=0 for the composition, and the sequence of X11 key events will be
- // XK_Multi_key, XK_apostrophe, **NoSymbol**, and XK_e.
+ // XK_Multi_key, XK_apostrophe, **NoSymbol**, and XK_e. If the user used
+ // shift key and/or caps lock key, state can be ShiftMask, LockMask or both.
//
// We have to send these fabricated key events to XIM so it can correctly
// handle the character compositions.
+ const unsigned int shift_lock_mask = ShiftMask | LockMask;
const bool fabricated_by_xim =
- xevent->xkey.keycode == 0 && xevent->xkey.state == 0;
+ xevent->xkey.keycode == 0 &&
+ (xevent->xkey.state & ~shift_lock_mask) == 0;
const int ime_fabricated_flag =
fabricated_by_xim ? ui::EF_IME_FABRICATED_KEY : 0;
#endif
diff --git a/ui/events/x/events_x_unittest.cc b/ui/events/x/events_x_unittest.cc
index 3a1c08c..5047c59 100644
--- a/ui/events/x/events_x_unittest.cc
+++ b/ui/events/x/events_x_unittest.cc
@@ -279,7 +279,6 @@ TEST(EventsXTest, NumpadKeyEvents) {
struct {
bool is_numpad_key;
int x_keysym;
- ui::KeyboardCode ui_keycode;
} keys[] = {
// XK_KP_Space and XK_KP_Equal are the extrema in the conventional
// keysymdef.h numbering.
@@ -429,4 +428,36 @@ TEST(EventsXTest, FunctionKeyEvents) {
EXPECT_FALSE(HasFunctionKeyFlagSetIfSupported(display, XK_F35 + 1));
}
+#if !defined(OS_CHROMEOS)
+TEST(EventsXTest, ImeFabricatedKeyEvents) {
+ Display* display = gfx::GetXDisplay();
+
+ unsigned int state_to_be_fabricated[] = {
+ 0, ShiftMask, LockMask, ShiftMask | LockMask,
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(state_to_be_fabricated); ++i) {
+ unsigned int state = state_to_be_fabricated[i];
+ for (int is_char = 0; is_char < 2; ++is_char) {
+ XEvent x_event;
+ InitKeyEvent(display, &x_event, true, 0, state);
+ ui::KeyEvent key_event(&x_event, is_char);
+ EXPECT_TRUE(key_event.flags() & ui::EF_IME_FABRICATED_KEY);
+ }
+ }
+
+ unsigned int state_to_be_not_fabricated[] = {
+ ControlMask, Mod1Mask, Mod2Mask, ShiftMask | ControlMask,
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(state_to_be_not_fabricated); ++i) {
+ unsigned int state = state_to_be_not_fabricated[i];
+ for (int is_char = 0; is_char < 2; ++is_char) {
+ XEvent x_event;
+ InitKeyEvent(display, &x_event, true, 0, state);
+ ui::KeyEvent key_event(&x_event, is_char);
+ EXPECT_FALSE(key_event.flags() & ui::EF_IME_FABRICATED_KEY);
+ }
+ }
+}
+#endif
+
} // namespace ui