OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/base/ime/input_method_ibus.h" | 5 #include "ui/base/ime/input_method_ibus.h" |
6 | 6 |
7 #include <X11/X.h> | 7 #include <X11/X.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 #include <X11/Xutil.h> | 9 #include <X11/Xutil.h> |
10 #undef FocusIn | 10 #undef FocusIn |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 // http://ibus.googlecode.com/svn/docs/ibus-1.4/ibus-ibustypes.html#IBusCapabili
te | 46 // http://ibus.googlecode.com/svn/docs/ibus-1.4/ibus-ibustypes.html#IBusCapabili
te |
47 const uint32 kIBusCapabilityPreeditText = 1U; | 47 const uint32 kIBusCapabilityPreeditText = 1U; |
48 const uint32 kIBusCapabilityFocus = 8U; | 48 const uint32 kIBusCapabilityFocus = 8U; |
49 const uint32 kIBusCapabilitySurroundingText = 32U; | 49 const uint32 kIBusCapabilitySurroundingText = 32U; |
50 | 50 |
51 XKeyEvent* GetKeyEvent(XEvent* event) { | 51 XKeyEvent* GetKeyEvent(XEvent* event) { |
52 DCHECK(event && (event->type == KeyPress || event->type == KeyRelease)); | 52 DCHECK(event && (event->type == KeyPress || event->type == KeyRelease)); |
53 return &event->xkey; | 53 return &event->xkey; |
54 } | 54 } |
55 | 55 |
56 // Converts X (and ibus) flags to event flags. | 56 // Converts X (and ibus) state to event flags. |
57 int EventFlagsFromXFlags(unsigned int flags) { | 57 int EventFlagsFromXState(unsigned int state) { |
58 return (flags & LockMask ? ui::EF_CAPS_LOCK_DOWN : 0) | | 58 return (state & LockMask ? ui::EF_CAPS_LOCK_DOWN : 0) | |
59 (flags & ControlMask ? ui::EF_CONTROL_DOWN : 0) | | 59 (state & ControlMask ? ui::EF_CONTROL_DOWN : 0) | |
60 (flags & ShiftMask ? ui::EF_SHIFT_DOWN : 0) | | 60 (state & ShiftMask ? ui::EF_SHIFT_DOWN : 0) | |
61 (flags & Mod1Mask ? ui::EF_ALT_DOWN : 0) | | 61 (state & Mod1Mask ? ui::EF_ALT_DOWN : 0) | |
62 (flags & Button1Mask ? ui::EF_LEFT_MOUSE_BUTTON : 0) | | 62 (state & Button1Mask ? ui::EF_LEFT_MOUSE_BUTTON : 0) | |
63 (flags & Button2Mask ? ui::EF_MIDDLE_MOUSE_BUTTON : 0) | | 63 (state & Button2Mask ? ui::EF_MIDDLE_MOUSE_BUTTON : 0) | |
64 (flags & Button3Mask ? ui::EF_RIGHT_MOUSE_BUTTON : 0); | 64 (state & Button3Mask ? ui::EF_RIGHT_MOUSE_BUTTON : 0); |
65 } | 65 } |
66 | 66 |
67 // Converts X flags to ibus key state flags. | 67 // Converts X state to ibus key and button state. |
68 uint32 IBusStateFromXFlags(unsigned int flags) { | 68 uint32 IBusStateFromXState(unsigned int state) { |
69 return (flags & (LockMask | ControlMask | ShiftMask | Mod1Mask | | 69 return (state & (LockMask | ControlMask | ShiftMask | Mod1Mask | |
70 Button1Mask | Button2Mask | Button3Mask)); | 70 Button1Mask | Button2Mask | Button3Mask)); |
71 } | 71 } |
72 | 72 |
73 chromeos::IBusInputContextClient* GetInputContextClient() { | 73 chromeos::IBusInputContextClient* GetInputContextClient() { |
74 return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); | 74 return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); |
75 } | 75 } |
76 | 76 |
77 // Converts gfx::Rect to ibus::Rect. | 77 // Converts gfx::Rect to ibus::Rect. |
78 chromeos::ibus::Rect GfxRectToIBusRect(const gfx::Rect& rect) { | 78 chromeos::ibus::Rect GfxRectToIBusRect(const gfx::Rect& rect) { |
79 return chromeos::ibus::Rect(rect.x(), rect.y(), rect.width(), rect.height()); | 79 return chromeos::ibus::Rect(rect.x(), rect.y(), rect.width(), rect.height()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 | 133 |
134 // Create the input context if the connection is already established. | 134 // Create the input context if the connection is already established. |
135 if (IsConnected()) | 135 if (IsConnected()) |
136 CreateContext(); | 136 CreateContext(); |
137 | 137 |
138 InputMethodBase::Init(focused); | 138 InputMethodBase::Init(focused); |
139 } | 139 } |
140 | 140 |
141 void InputMethodIBus::ProcessKeyEventDone(uint32 id, | 141 void InputMethodIBus::ProcessKeyEventDone(uint32 id, |
142 XEvent* event, | 142 XEvent* event, |
143 uint32 keyval, | 143 uint32 ibus_keyval, |
| 144 uint32 ibus_keycode, |
| 145 uint32 ibus_state, |
144 bool is_handled) { | 146 bool is_handled) { |
145 DCHECK(event); | 147 DCHECK(event); |
146 std::set<uint32>::iterator it = pending_key_events_.find(id); | 148 std::set<uint32>::iterator it = pending_key_events_.find(id); |
147 | 149 |
148 if (it == pending_key_events_.end()) | 150 if (it == pending_key_events_.end()) |
149 return; // Abandoned key event. | 151 return; // Abandoned key event. |
150 if (event->type == KeyPress || event->type == KeyRelease) | 152 if (event->type == KeyPress || event->type == KeyRelease) |
151 ProcessKeyEventPostIME(event, keyval, is_handled); | 153 ProcessKeyEventPostIME(event, ibus_keyval, ibus_keycode, ibus_state, |
| 154 is_handled); |
152 | 155 |
153 // Do not use |it| for erasing, ProcessKeyEventPostIME may change the | 156 // Do not use |it| for erasing, ProcessKeyEventPostIME may change the |
154 // |pending_key_events_|. | 157 // |pending_key_events_|. |
155 pending_key_events_.erase(id); | 158 pending_key_events_.erase(id); |
156 } | 159 } |
157 | 160 |
158 bool InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { | 161 bool InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { |
159 DCHECK(native_event && (native_event->type == KeyPress || | 162 DCHECK(native_event && (native_event->type == KeyPress || |
160 native_event->type == KeyRelease)); | 163 native_event->type == KeyRelease)); |
161 DCHECK(system_toplevel_window_focused()); | 164 DCHECK(system_toplevel_window_focused()); |
162 | 165 |
163 uint32 ibus_keyval = 0; | 166 uint32 ibus_keyval = 0; |
164 uint32 ibus_keycode = 0; | 167 uint32 ibus_keycode = 0; |
165 uint32 ibus_state = 0; | 168 uint32 ibus_state = 0; |
166 IBusKeyEventFromNativeKeyEvent( | 169 IBusKeyEventFromNativeKeyEvent( |
167 native_event, &ibus_keyval, &ibus_keycode, &ibus_state); | 170 native_event, |
| 171 &ibus_keyval, &ibus_keycode, &ibus_state); |
168 | 172 |
169 // If |context_| is not usable, then we can only dispatch the key event as is. | 173 // If |context_| is not usable, then we can only dispatch the key event as is. |
170 // We also dispatch the key event directly if the current text input type is | 174 // We also dispatch the key event directly if the current text input type is |
171 // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. | 175 // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. |
172 // Note: We need to send the key event to ibus even if the |context_| is not | 176 // Note: We need to send the key event to ibus even if the |context_| is not |
173 // enabled, so that ibus can have a chance to enable the |context_|. | 177 // enabled, so that ibus can have a chance to enable the |context_|. |
174 if (!context_focused_ || | 178 if (!context_focused_ || |
175 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD || | 179 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD || |
176 !GetInputContextClient() || | 180 !GetInputContextClient() || |
177 GetInputContextClient()->IsXKBLayout()) { | 181 GetInputContextClient()->IsXKBLayout()) { |
178 if (native_event->type == KeyPress) | 182 if (native_event->type == KeyPress) |
179 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval); | 183 ProcessUnfilteredKeyPressEvent(native_event, |
| 184 ibus_keyval, ibus_keycode, ibus_state); |
180 else | 185 else |
181 DispatchKeyEventPostIME(native_event); | 186 DispatchKeyEventPostIME(native_event); |
182 return true; | 187 return true; |
183 } | 188 } |
184 | 189 |
185 pending_key_events_.insert(current_keyevent_id_); | 190 pending_key_events_.insert(current_keyevent_id_); |
186 | 191 |
187 // Since |native_event| might be treated as XEvent whose size is bigger than | 192 // Since |native_event| might be treated as XEvent whose size is bigger than |
188 // XKeyEvent e.g. in CopyNativeEvent() in ui/base/events/event.cc, allocating | 193 // XKeyEvent e.g. in CopyNativeEvent() in ui/base/events/event.cc, allocating |
189 // |event| as XKeyEvent and casting it to XEvent is unsafe. crbug.com/151884 | 194 // |event| as XKeyEvent and casting it to XEvent is unsafe. crbug.com/151884 |
190 XEvent* event = new XEvent; | 195 XEvent* event = new XEvent; |
191 *event = *native_event; | 196 *event = *native_event; |
192 const chromeos::IBusInputContextClient::ProcessKeyEventCallback callback = | 197 const chromeos::IBusInputContextClient::ProcessKeyEventCallback callback = |
193 base::Bind(&InputMethodIBus::ProcessKeyEventDone, | 198 base::Bind(&InputMethodIBus::ProcessKeyEventDone, |
194 weak_ptr_factory_.GetWeakPtr(), | 199 weak_ptr_factory_.GetWeakPtr(), |
195 current_keyevent_id_, | 200 current_keyevent_id_, |
196 base::Owned(event), // Pass the ownership of |event|. | 201 base::Owned(event), // Pass the ownership of |event|. |
197 ibus_keyval); | 202 ibus_keyval, |
| 203 ibus_keycode, |
| 204 ibus_state); |
198 | 205 |
199 GetInputContextClient()->ProcessKeyEvent(ibus_keyval, | 206 GetInputContextClient()->ProcessKeyEvent(ibus_keyval, |
200 ibus_keycode, | 207 ibus_keycode, |
201 ibus_state, | 208 ibus_state, |
202 callback, | 209 callback, |
203 base::Bind(callback, false)); | 210 base::Bind(callback, false)); |
204 ++current_keyevent_id_; | 211 ++current_keyevent_id_; |
205 | 212 |
206 // We don't want to suppress the result generated by this key event, but it | 213 // We don't want to suppress the result generated by this key event, but it |
207 // may cause problem. See comment in ResetContext() method. | 214 // may cause problem. See comment in ResetContext() method. |
208 suppress_next_result_ = false; | 215 suppress_next_result_ = false; |
209 return true; | 216 return true; |
210 } | 217 } |
211 | 218 |
212 bool InputMethodIBus::DispatchFabricatedKeyEvent(const ui::KeyEvent& event) { | 219 bool InputMethodIBus::DispatchFabricatedKeyEvent(const ui::KeyEvent& event) { |
213 // TODO(bryeung): The fabricated events should also pass through IME. | 220 // TODO(bryeung): The fabricated events should also pass through IME. |
214 if (event.type() == ET_KEY_PRESSED) { | 221 if (event.type() == ET_KEY_PRESSED) { |
215 ProcessUnfilteredFabricatedKeyPressEvent( | 222 ProcessUnfilteredFabricatedKeyPressEvent( |
216 ET_KEY_PRESSED, event.key_code(), event.flags(), 0); | 223 ET_KEY_PRESSED, event.key_code(), event.flags(), 0, 0); |
217 } else { | 224 } else { |
218 DispatchFabricatedKeyEventPostIME( | 225 DispatchFabricatedKeyEventPostIME( |
219 ET_KEY_RELEASED, | 226 ET_KEY_RELEASED, |
220 event.key_code(), | 227 event.key_code(), |
221 event.flags()); | 228 event.flags()); |
222 } | 229 } |
223 return true; | 230 return true; |
224 } | 231 } |
225 | 232 |
226 void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) { | 233 void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) { |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 uint32 capability = kIBusCapabilityFocus | kIBusCapabilitySurroundingText; | 454 uint32 capability = kIBusCapabilityFocus | kIBusCapabilitySurroundingText; |
448 if (CanComposeInline()) | 455 if (CanComposeInline()) |
449 capability |= kIBusCapabilityPreeditText; | 456 capability |= kIBusCapabilityPreeditText; |
450 GetInputContextClient()->SetCapabilities(capability); | 457 GetInputContextClient()->SetCapabilities(capability); |
451 } | 458 } |
452 } | 459 } |
453 | 460 |
454 void InputMethodIBus::ProcessKeyEventPostIME( | 461 void InputMethodIBus::ProcessKeyEventPostIME( |
455 const base::NativeEvent& native_event, | 462 const base::NativeEvent& native_event, |
456 uint32 ibus_keyval, | 463 uint32 ibus_keyval, |
| 464 uint32 ibus_keycode, |
| 465 uint32 ibus_state, |
457 bool handled) { | 466 bool handled) { |
458 TextInputClient* client = GetTextInputClient(); | 467 TextInputClient* client = GetTextInputClient(); |
459 | 468 |
460 if (!client) { | 469 if (!client) { |
461 // As ibus works asynchronously, there is a chance that the focused client | 470 // As ibus works asynchronously, there is a chance that the focused client |
462 // loses focus before this method gets called. | 471 // loses focus before this method gets called. |
463 DispatchKeyEventPostIME(native_event); | 472 DispatchKeyEventPostIME(native_event); |
464 return; | 473 return; |
465 } | 474 } |
466 | 475 |
467 if (native_event->type == KeyPress && handled) | 476 if (native_event->type == KeyPress && handled) |
468 ProcessFilteredKeyPressEvent(native_event); | 477 ProcessFilteredKeyPressEvent(native_event); |
469 | 478 |
470 // In case the focus was changed by the key event. The |context_| should have | 479 // In case the focus was changed by the key event. The |context_| should have |
471 // been reset when the focused window changed. | 480 // been reset when the focused window changed. |
472 if (client != GetTextInputClient()) | 481 if (client != GetTextInputClient()) |
473 return; | 482 return; |
474 | 483 |
475 if (HasInputMethodResult()) | 484 if (HasInputMethodResult()) |
476 ProcessInputMethodResult(native_event, handled); | 485 ProcessInputMethodResult(native_event, handled); |
477 | 486 |
478 // In case the focus was changed when sending input method results to the | 487 // In case the focus was changed when sending input method results to the |
479 // focused window. | 488 // focused window. |
480 if (client != GetTextInputClient()) | 489 if (client != GetTextInputClient()) |
481 return; | 490 return; |
482 | 491 |
483 if (native_event->type == KeyPress && !handled) | 492 if (native_event->type == KeyPress && !handled) |
484 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval); | 493 ProcessUnfilteredKeyPressEvent(native_event, |
| 494 ibus_keyval, ibus_keycode, ibus_state); |
485 else if (native_event->type == KeyRelease) | 495 else if (native_event->type == KeyRelease) |
486 DispatchKeyEventPostIME(native_event); | 496 DispatchKeyEventPostIME(native_event); |
487 } | 497 } |
488 | 498 |
489 void InputMethodIBus::IBusKeyEventFromNativeKeyEvent( | 499 void InputMethodIBus::IBusKeyEventFromNativeKeyEvent( |
490 const base::NativeEvent& native_event, | 500 const base::NativeEvent& native_event, |
491 uint32* ibus_keyval, | 501 uint32* ibus_keyval, |
492 uint32* ibus_keycode, | 502 uint32* ibus_keycode, |
493 uint32* ibus_state) { | 503 uint32* ibus_state) { |
494 DCHECK(native_event); // A fabricated event is not supported here. | 504 DCHECK(native_event); // A fabricated event is not supported here. |
495 XKeyEvent* x_key = GetKeyEvent(native_event); | 505 XKeyEvent* x_key = GetKeyEvent(native_event); |
496 | 506 |
497 // Yes, ibus uses X11 keysym. We cannot use XLookupKeysym(), which doesn't | 507 // Yes, ibus uses X11 keysym. We cannot use XLookupKeysym(), which doesn't |
498 // translate Shift and CapsLock states. | 508 // translate Shift and CapsLock states. |
499 KeySym keysym = NoSymbol; | 509 KeySym keysym = NoSymbol; |
500 ::XLookupString(x_key, NULL, 0, &keysym, NULL); | 510 ::XLookupString(x_key, NULL, 0, &keysym, NULL); |
501 *ibus_keyval = keysym; | 511 *ibus_keyval = keysym; |
502 *ibus_keycode = x_key->keycode; | 512 *ibus_keycode = x_key->keycode; |
503 *ibus_state = IBusStateFromXFlags(x_key->state); | 513 *ibus_state = IBusStateFromXState(x_key->state); |
504 if (native_event->type == KeyRelease) | 514 if (native_event->type == KeyRelease) |
505 *ibus_state |= kIBusReleaseMask; | 515 *ibus_state |= kIBusReleaseMask; |
506 } | 516 } |
507 | 517 |
508 void InputMethodIBus::ProcessFilteredKeyPressEvent( | 518 void InputMethodIBus::ProcessFilteredKeyPressEvent( |
509 const base::NativeEvent& native_event) { | 519 const base::NativeEvent& native_event) { |
510 if (NeedInsertChar()) | 520 if (NeedInsertChar()) |
511 DispatchKeyEventPostIME(native_event); | 521 DispatchKeyEventPostIME(native_event); |
512 else | 522 else |
513 DispatchFabricatedKeyEventPostIME( | 523 DispatchFabricatedKeyEventPostIME( |
514 ET_KEY_PRESSED, | 524 ET_KEY_PRESSED, |
515 VKEY_PROCESSKEY, | 525 VKEY_PROCESSKEY, |
516 EventFlagsFromXFlags(GetKeyEvent(native_event)->state)); | 526 EventFlagsFromXState(GetKeyEvent(native_event)->state)); |
517 } | 527 } |
518 | 528 |
519 void InputMethodIBus::ProcessUnfilteredKeyPressEvent( | 529 void InputMethodIBus::ProcessUnfilteredKeyPressEvent( |
520 const base::NativeEvent& native_event, | 530 const base::NativeEvent& native_event, |
521 uint32 ibus_keyval) { | 531 uint32 ibus_keyval, |
| 532 uint32 ibus_keycode, |
| 533 uint32 ibus_state) { |
522 // For a fabricated event, ProcessUnfilteredFabricatedKeyPressEvent should be | 534 // For a fabricated event, ProcessUnfilteredFabricatedKeyPressEvent should be |
523 // called instead. | 535 // called instead. |
524 DCHECK(native_event); | 536 DCHECK(native_event); |
525 | 537 |
526 TextInputClient* client = GetTextInputClient(); | 538 TextInputClient* client = GetTextInputClient(); |
527 DispatchKeyEventPostIME(native_event); | 539 DispatchKeyEventPostIME(native_event); |
528 | 540 |
529 // We shouldn't dispatch the character anymore if the key event dispatch | 541 // We shouldn't dispatch the character anymore if the key event dispatch |
530 // caused focus change. For example, in the following scenario, | 542 // caused focus change. For example, in the following scenario, |
531 // 1. visit a web page which has a <textarea>. | 543 // 1. visit a web page which has a <textarea>. |
532 // 2. click Omnibox. | 544 // 2. click Omnibox. |
533 // 3. enable Korean IME, press A, then press Tab to move the focus to the web | 545 // 3. enable Korean IME, press A, then press Tab to move the focus to the web |
534 // page. | 546 // page. |
535 // We should return here not to send the Tab key event to RWHV. | 547 // We should return here not to send the Tab key event to RWHV. |
536 if (client != GetTextInputClient()) | 548 if (client != GetTextInputClient()) |
537 return; | 549 return; |
538 | 550 |
539 const uint32 state = | 551 const uint32 event_flags = EventFlagsFromXState(ibus_state); |
540 EventFlagsFromXFlags(GetKeyEvent(native_event)->state); | |
541 | 552 |
542 // Process compose and dead keys | 553 // Process compose and dead keys |
543 if (ProcessUnfilteredKeyPressEventWithCharacterComposer(ibus_keyval, state)) | 554 if (ProcessUnfilteredKeyPressEventWithCharacterComposer( |
| 555 ibus_keyval, ibus_keycode, event_flags)) |
544 return; | 556 return; |
545 | 557 |
546 // If a key event was not filtered by |context_| and |character_composer_|, | 558 // If a key event was not filtered by |context_| and |character_composer_|, |
547 // then it means the key event didn't generate any result text. So we need | 559 // then it means the key event didn't generate any result text. So we need |
548 // to send corresponding character to the focused text input client. | 560 // to send corresponding character to the focused text input client. |
549 client = GetTextInputClient(); | 561 client = GetTextInputClient(); |
550 | 562 |
551 uint16 ch = 0; | 563 uint16 ch = 0; |
552 if (!(state & ui::EF_CONTROL_DOWN)) | 564 if (!(event_flags & ui::EF_CONTROL_DOWN)) |
553 ch = ui::GetCharacterFromXEvent(native_event); | 565 ch = ui::GetCharacterFromXEvent(native_event); |
554 if (!ch) { | 566 if (!ch) { |
555 ch = ui::GetCharacterFromKeyCode( | 567 ch = ui::GetCharacterFromKeyCode( |
556 ui::KeyboardCodeFromNative(native_event), state); | 568 ui::KeyboardCodeFromNative(native_event), event_flags); |
557 } | 569 } |
558 | 570 |
559 if (client && ch) | 571 if (client && ch) |
560 client->InsertChar(ch, state); | 572 client->InsertChar(ch, event_flags); |
561 } | 573 } |
562 | 574 |
563 void InputMethodIBus::ProcessUnfilteredFabricatedKeyPressEvent( | 575 void InputMethodIBus::ProcessUnfilteredFabricatedKeyPressEvent( |
564 EventType type, | 576 EventType type, |
565 KeyboardCode key_code, | 577 KeyboardCode key_code, |
566 int flags, | 578 int event_flags, |
567 uint32 ibus_keyval) { | 579 uint32 ibus_keyval, |
| 580 uint32 ibus_keycode) { |
568 TextInputClient* client = GetTextInputClient(); | 581 TextInputClient* client = GetTextInputClient(); |
569 DispatchFabricatedKeyEventPostIME(type, key_code, flags); | 582 DispatchFabricatedKeyEventPostIME(type, key_code, event_flags); |
570 | 583 |
571 if (client != GetTextInputClient()) | 584 if (client != GetTextInputClient()) |
572 return; | 585 return; |
573 | 586 |
574 if (ProcessUnfilteredKeyPressEventWithCharacterComposer(ibus_keyval, flags)) | 587 if (ProcessUnfilteredKeyPressEventWithCharacterComposer( |
| 588 ibus_keyval, ibus_keycode, event_flags)) |
575 return; | 589 return; |
576 | 590 |
577 client = GetTextInputClient(); | 591 client = GetTextInputClient(); |
578 const uint16 ch = ui::GetCharacterFromKeyCode(key_code, flags); | 592 const uint16 ch = ui::GetCharacterFromKeyCode(key_code, event_flags); |
579 if (client && ch) | 593 if (client && ch) |
580 client->InsertChar(ch, flags); | 594 client->InsertChar(ch, event_flags); |
581 } | 595 } |
582 | 596 |
583 bool InputMethodIBus::ProcessUnfilteredKeyPressEventWithCharacterComposer( | 597 bool InputMethodIBus::ProcessUnfilteredKeyPressEventWithCharacterComposer( |
584 uint32 ibus_keyval, | 598 uint32 ibus_keyval, |
585 uint32 state) { | 599 uint32 ibus_keycode, |
| 600 int event_flags) { |
586 // We don't filter key presses for inappropriate input types. | 601 // We don't filter key presses for inappropriate input types. |
587 const TextInputType text_input_type = GetTextInputType(); | 602 const TextInputType text_input_type = GetTextInputType(); |
588 if (text_input_type == TEXT_INPUT_TYPE_NONE || | 603 if (text_input_type == TEXT_INPUT_TYPE_NONE || |
589 text_input_type == TEXT_INPUT_TYPE_PASSWORD) | 604 text_input_type == TEXT_INPUT_TYPE_PASSWORD) |
590 return false; | 605 return false; |
591 | 606 |
592 // Do nothing if the key press is not filtered by our composer. | 607 // Do nothing if the key press is not filtered by our composer. |
593 if (!character_composer_.FilterKeyPress(ibus_keyval, state)) | 608 if (!character_composer_.FilterKeyPress(ibus_keyval, ibus_keycode, |
| 609 event_flags)) |
594 return false; | 610 return false; |
595 | 611 |
596 TextInputClient* client = GetTextInputClient(); | 612 TextInputClient* client = GetTextInputClient(); |
597 if (!client) // Do nothing if we cannot get the client. | 613 if (!client) // Do nothing if we cannot get the client. |
598 return true; | 614 return true; |
599 | 615 |
600 // Insert composed character. | 616 // Insert composed character. |
601 const string16 composed = character_composer_.composed_character(); | 617 const string16 composed = character_composer_.composed_character(); |
602 if (!composed.empty()) { | 618 if (!composed.empty()) { |
603 if (composed.size() == 1) { | 619 if (composed.size() == 1) { |
604 client->InsertChar(composed[0], state); | 620 client->InsertChar(composed[0], event_flags); |
605 } else { | 621 } else { |
606 CompositionText composition; | 622 CompositionText composition; |
607 composition.text = composed; | 623 composition.text = composed; |
608 client->SetCompositionText(composition); | 624 client->SetCompositionText(composition); |
609 client->ConfirmCompositionText(); | 625 client->ConfirmCompositionText(); |
610 } | 626 } |
611 } | 627 } |
612 return true; | 628 return true; |
613 } | 629 } |
614 | 630 |
615 void InputMethodIBus::ProcessInputMethodResult( | 631 void InputMethodIBus::ProcessInputMethodResult( |
616 const base::NativeEvent& native_event, | 632 const base::NativeEvent& native_event, |
617 bool handled) { | 633 bool handled) { |
618 TextInputClient* client = GetTextInputClient(); | 634 TextInputClient* client = GetTextInputClient(); |
619 DCHECK(client); | 635 DCHECK(client); |
620 | 636 |
621 if (result_text_.length()) { | 637 if (result_text_.length()) { |
622 if (handled && NeedInsertChar()) { | 638 if (handled && NeedInsertChar()) { |
623 const uint32 state = | 639 const uint32 state = |
624 EventFlagsFromXFlags(GetKeyEvent(native_event)->state); | 640 EventFlagsFromXState(GetKeyEvent(native_event)->state); |
625 for (string16::const_iterator i = result_text_.begin(); | 641 for (string16::const_iterator i = result_text_.begin(); |
626 i != result_text_.end(); ++i) { | 642 i != result_text_.end(); ++i) { |
627 client->InsertChar(*i, state); | 643 client->InsertChar(*i, state); |
628 } | 644 } |
629 } else { | 645 } else { |
630 client->InsertText(result_text_); | 646 client->InsertText(result_text_); |
631 composing_text_ = false; | 647 composing_text_ = false; |
632 } | 648 } |
633 } | 649 } |
634 | 650 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 // focused text input client does not support text input. | 705 // focused text input client does not support text input. |
690 if (pending_key_events_.empty() && !IsTextInputTypeNone()) { | 706 if (pending_key_events_.empty() && !IsTextInputTypeNone()) { |
691 SendFakeProcessKeyEvent(true); | 707 SendFakeProcessKeyEvent(true); |
692 GetTextInputClient()->InsertText(utf16_text); | 708 GetTextInputClient()->InsertText(utf16_text); |
693 SendFakeProcessKeyEvent(false); | 709 SendFakeProcessKeyEvent(false); |
694 result_text_.clear(); | 710 result_text_.clear(); |
695 } | 711 } |
696 } | 712 } |
697 | 713 |
698 void InputMethodIBus::ForwardKeyEvent(uint32 keyval, | 714 void InputMethodIBus::ForwardKeyEvent(uint32 keyval, |
699 uint32 keycode, | 715 uint32 keycode, |
700 uint32 state) { | 716 uint32 state) { |
701 KeyboardCode ui_key_code = KeyboardCodeFromXKeysym(keyval); | 717 KeyboardCode ui_key_code = KeyboardCodeFromXKeysym(keyval); |
702 if (!ui_key_code) | 718 if (!ui_key_code) |
703 return; | 719 return; |
704 | 720 |
705 const EventType event_type = | 721 const EventType event_type = |
706 (state & kIBusReleaseMask) ? ET_KEY_RELEASED : ET_KEY_PRESSED; | 722 (state & kIBusReleaseMask) ? ET_KEY_RELEASED : ET_KEY_PRESSED; |
707 const int event_flags = EventFlagsFromXFlags(state); | 723 const int event_flags = EventFlagsFromXState(state); |
708 | 724 |
709 // It is not clear when the input method will forward us a fake key event. | 725 // It is not clear when the input method will forward us a fake key event. |
710 // If there is a pending key event, then we may already received some input | 726 // If there is a pending key event, then we may already received some input |
711 // method results, so we dispatch this fake key event directly rather than | 727 // method results, so we dispatch this fake key event directly rather than |
712 // calling ProcessKeyEventPostIME(), which will clear pending input method | 728 // calling ProcessKeyEventPostIME(), which will clear pending input method |
713 // results. | 729 // results. |
714 if (event_type == ET_KEY_PRESSED) { | 730 if (event_type == ET_KEY_PRESSED) { |
715 ProcessUnfilteredFabricatedKeyPressEvent( | 731 ProcessUnfilteredFabricatedKeyPressEvent( |
716 event_type, ui_key_code, event_flags, keyval); | 732 event_type, ui_key_code, event_flags, keyval, keycode); |
717 } else { | 733 } else { |
718 DispatchFabricatedKeyEventPostIME(event_type, ui_key_code, event_flags); | 734 DispatchFabricatedKeyEventPostIME(event_type, ui_key_code, event_flags); |
719 } | 735 } |
720 } | 736 } |
721 | 737 |
722 void InputMethodIBus::ShowPreeditText() { | 738 void InputMethodIBus::ShowPreeditText() { |
723 if (suppress_next_result_ || IsTextInputTypeNone()) | 739 if (suppress_next_result_ || IsTextInputTypeNone()) |
724 return; | 740 return; |
725 | 741 |
726 composing_text_ = true; | 742 composing_text_ = true; |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 } | 965 } |
950 | 966 |
951 // Use a black thin underline by default. | 967 // Use a black thin underline by default. |
952 if (out_composition->underlines.empty()) { | 968 if (out_composition->underlines.empty()) { |
953 out_composition->underlines.push_back(CompositionUnderline( | 969 out_composition->underlines.push_back(CompositionUnderline( |
954 0, length, SK_ColorBLACK, false /* thick */)); | 970 0, length, SK_ColorBLACK, false /* thick */)); |
955 } | 971 } |
956 } | 972 } |
957 | 973 |
958 } // namespace ui | 974 } // namespace ui |
OLD | NEW |