Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: ui/base/ime/input_method_ibus.cc

Issue 15816003: Supports unicode composition(Ctrl+Shift+U) with C-S pressed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added a TODO. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/base/ime/input_method_ibus.h ('k') | ui/base/ime/input_method_ibus_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « ui/base/ime/input_method_ibus.h ('k') | ui/base/ime/input_method_ibus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698