| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/ime/input_method_ibus.h" | 5 #include "views/ime/input_method_ibus.h" |
| 6 | 6 |
| 7 #include <ibus.h> | 7 #include <ibus.h> |
| 8 #if defined(TOUCH_UI) | 8 #if defined(TOUCH_UI) |
| 9 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
| 10 #include <X11/Xutil.h> | 10 #include <X11/Xutil.h> |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 key.set_character(character_); | 258 key.set_character(character_); |
| 259 key.set_unmodified_character(unmodified_character_); | 259 key.set_unmodified_character(unmodified_character_); |
| 260 } | 260 } |
| 261 input_method_->ProcessKeyEventPostIME(key, ibus_keyval_, handled); | 261 input_method_->ProcessKeyEventPostIME(key, ibus_keyval_, handled); |
| 262 } | 262 } |
| 263 | 263 |
| 264 // InputMethodIBus::PendingCreateICRequest implementation --------------------- | 264 // InputMethodIBus::PendingCreateICRequest implementation --------------------- |
| 265 class InputMethodIBus::PendingCreateICRequest { | 265 class InputMethodIBus::PendingCreateICRequest { |
| 266 public: | 266 public: |
| 267 PendingCreateICRequest(InputMethodIBus* input_method, | 267 PendingCreateICRequest(InputMethodIBus* input_method, |
| 268 PendingCreateICRequest** request_ptr, | 268 PendingCreateICRequest** request_ptr); |
| 269 bool fake); | |
| 270 ~PendingCreateICRequest(); | 269 ~PendingCreateICRequest(); |
| 271 | 270 |
| 272 // Abandon this pending key event. Its result will just be discarded. | 271 // Abandon this pending key event. Its result will just be discarded. |
| 273 void abandon() { | 272 void abandon() { |
| 274 input_method_ = NULL; | 273 input_method_ = NULL; |
| 275 request_ptr_ = NULL; | 274 request_ptr_ = NULL; |
| 276 } | 275 } |
| 277 | 276 |
| 278 // Stores the result input context to |input_method_|, or abandon it if | 277 // Stores the result input context to |input_method_|, or abandon it if |
| 279 // |input_method_| is NULL. | 278 // |input_method_| is NULL. |
| 280 void StoreOrAbandonInputContext(IBusInputContext* ic); | 279 void StoreOrAbandonInputContext(IBusInputContext* ic); |
| 281 | 280 |
| 282 private: | 281 private: |
| 283 InputMethodIBus* input_method_; | 282 InputMethodIBus* input_method_; |
| 284 PendingCreateICRequest** request_ptr_; | 283 PendingCreateICRequest** request_ptr_; |
| 285 bool fake_; | |
| 286 }; | 284 }; |
| 287 | 285 |
| 288 InputMethodIBus::PendingCreateICRequest::PendingCreateICRequest( | 286 InputMethodIBus::PendingCreateICRequest::PendingCreateICRequest( |
| 289 InputMethodIBus* input_method, | 287 InputMethodIBus* input_method, |
| 290 PendingCreateICRequest** request_ptr, | 288 PendingCreateICRequest** request_ptr) |
| 291 bool fake) | |
| 292 : input_method_(input_method), | 289 : input_method_(input_method), |
| 293 request_ptr_(request_ptr), | 290 request_ptr_(request_ptr) { |
| 294 fake_(fake) { | |
| 295 } | 291 } |
| 296 | 292 |
| 297 InputMethodIBus::PendingCreateICRequest::~PendingCreateICRequest() { | 293 InputMethodIBus::PendingCreateICRequest::~PendingCreateICRequest() { |
| 298 if (request_ptr_) { | 294 if (request_ptr_) { |
| 299 DCHECK_EQ(*request_ptr_, this); | 295 DCHECK_EQ(*request_ptr_, this); |
| 300 *request_ptr_ = NULL; | 296 *request_ptr_ = NULL; |
| 301 } | 297 } |
| 302 } | 298 } |
| 303 | 299 |
| 304 void InputMethodIBus::PendingCreateICRequest::StoreOrAbandonInputContext( | 300 void InputMethodIBus::PendingCreateICRequest::StoreOrAbandonInputContext( |
| 305 IBusInputContext* ic) { | 301 IBusInputContext* ic) { |
| 306 if (input_method_) { | 302 if (input_method_) { |
| 307 input_method_->SetContext(ic, fake_); | 303 input_method_->SetContext(ic); |
| 308 } else { | 304 } else { |
| 309 // ibus_proxy_destroy() will not really release the object, we still need | 305 // ibus_proxy_destroy() will not really release the object, we still need |
| 310 // to call g_object_unref() explicitly. | 306 // to call g_object_unref() explicitly. |
| 311 ibus_proxy_destroy(reinterpret_cast<IBusProxy *>(ic)); | 307 ibus_proxy_destroy(reinterpret_cast<IBusProxy *>(ic)); |
| 312 g_object_unref(ic); | 308 g_object_unref(ic); |
| 313 } | 309 } |
| 314 } | 310 } |
| 315 | 311 |
| 316 // InputMethodIBus implementation --------------------------------------------- | 312 // InputMethodIBus implementation --------------------------------------------- |
| 317 InputMethodIBus::InputMethodIBus(internal::InputMethodDelegate* delegate) | 313 InputMethodIBus::InputMethodIBus(internal::InputMethodDelegate* delegate) |
| 318 : context_(NULL), | 314 : context_(NULL), |
| 319 fake_context_(NULL), | |
| 320 pending_create_ic_request_(NULL), | 315 pending_create_ic_request_(NULL), |
| 321 pending_create_fake_ic_request_(NULL), | |
| 322 context_focused_(false), | 316 context_focused_(false), |
| 323 composing_text_(false), | 317 composing_text_(false), |
| 324 composition_changed_(false), | 318 composition_changed_(false), |
| 325 suppress_next_result_(false) { | 319 suppress_next_result_(false) { |
| 326 set_delegate(delegate); | 320 set_delegate(delegate); |
| 327 } | 321 } |
| 328 | 322 |
| 329 InputMethodIBus::~InputMethodIBus() { | 323 InputMethodIBus::~InputMethodIBus() { |
| 330 AbandonAllPendingKeyEvents(); | 324 AbandonAllPendingKeyEvents(); |
| 331 DestroyContext(); | 325 DestroyContext(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 | 366 |
| 373 void InputMethodIBus::DispatchKeyEvent(const KeyEvent& key) { | 367 void InputMethodIBus::DispatchKeyEvent(const KeyEvent& key) { |
| 374 DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED); | 368 DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED); |
| 375 DCHECK(widget_focused()); | 369 DCHECK(widget_focused()); |
| 376 | 370 |
| 377 guint32 ibus_keyval = 0; | 371 guint32 ibus_keyval = 0; |
| 378 guint32 ibus_keycode = 0; | 372 guint32 ibus_keycode = 0; |
| 379 guint32 ibus_state = 0; | 373 guint32 ibus_state = 0; |
| 380 IBusKeyEventFromViewsKeyEvent(key, &ibus_keyval, &ibus_keycode, &ibus_state); | 374 IBusKeyEventFromViewsKeyEvent(key, &ibus_keyval, &ibus_keycode, &ibus_state); |
| 381 | 375 |
| 382 // If |context_| is not usable and |fake_context_| is not created yet, then we | 376 // If |context_| is not usable, then we can only dispatch the key event as is. |
| 383 // can only dispatch the key event as is. We also dispatch the key event | 377 // We also dispatch the key event directly if the current text input type is |
| 384 // directly if the current text input type is ui::TEXT_INPUT_TYPE_PASSWORD, | 378 // ui::TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. |
| 385 // to bypass the input method. | |
| 386 // Note: We need to send the key event to ibus even if the |context_| is not | 379 // Note: We need to send the key event to ibus even if the |context_| is not |
| 387 // enabled, so that ibus can have a chance to enable the |context_|. | 380 // enabled, so that ibus can have a chance to enable the |context_|. |
| 388 if (!(context_focused_ || fake_context_) || | 381 if (!context_focused_ || |
| 389 GetTextInputType() == ui::TEXT_INPUT_TYPE_PASSWORD) { | 382 GetTextInputType() == ui::TEXT_INPUT_TYPE_PASSWORD) { |
| 390 if (key.type() == ui::ET_KEY_PRESSED) | 383 if (key.type() == ui::ET_KEY_PRESSED) |
| 391 ProcessUnfilteredKeyPressEvent(key, ibus_keyval); | 384 ProcessUnfilteredKeyPressEvent(key, ibus_keyval); |
| 392 else | 385 else |
| 393 DispatchKeyEventPostIME(key); | 386 DispatchKeyEventPostIME(key); |
| 394 return; | 387 return; |
| 395 } | 388 } |
| 396 | 389 |
| 397 PendingKeyEvent* pending_key = new PendingKeyEvent(this, key, ibus_keyval); | 390 PendingKeyEvent* pending_key = new PendingKeyEvent(this, key, ibus_keyval); |
| 398 pending_key_events_.insert(pending_key); | 391 pending_key_events_.insert(pending_key); |
| 399 | 392 |
| 400 // Note: | 393 // Note: |
| 401 // 1. We currently set timeout to -1, because ibus doesn't have a mechanism to | 394 // 1. We currently set timeout to -1, because ibus doesn't have a mechanism to |
| 402 // associate input method results to corresponding key event, thus there is | 395 // associate input method results to corresponding key event, thus there is |
| 403 // actually no way to abandon results generated by a specific key event. So we | 396 // actually no way to abandon results generated by a specific key event. So we |
| 404 // actually cannot abandon a specific key event and its result but accept | 397 // actually cannot abandon a specific key event and its result but accept |
| 405 // following key events and their results. So a timeout to abandon a key event | 398 // following key events and their results. So a timeout to abandon a key event |
| 406 // will not work. | 399 // will not work. |
| 407 // 2. We set GCancellable to NULL, because the operation of cancelling a async | 400 // 2. We set GCancellable to NULL, because the operation of cancelling a async |
| 408 // request also happens asynchronously, thus it's actually useless to us. | 401 // request also happens asynchronously, thus it's actually useless to us. |
| 409 // | 402 // |
| 410 // The fundemental problem of ibus' async API is: it uses Glib's GIO API to | 403 // The fundemental problem of ibus' async API is: it uses Glib's GIO API to |
| 411 // realize async communication, but in fact, GIO API is specially designed for | 404 // realize async communication, but in fact, GIO API is specially designed for |
| 412 // concurrent tasks, though it supports async communication as well, the API | 405 // concurrent tasks, though it supports async communication as well, the API |
| 413 // is much more complicated than an ordinary message based async communication | 406 // is much more complicated than an ordinary message based async communication |
| 414 // API (such as Chrome's IPC). | 407 // API (such as Chrome's IPC). |
| 415 // Thus it's very complicated, if not impossible, to implement a client that | 408 // Thus it's very complicated, if not impossible, to implement a client that |
| 416 // fully utilize asynchronous communication without potential problem. | 409 // fully utilize asynchronous communication without potential problem. |
| 417 ibus_input_context_process_key_event_async( | 410 ibus_input_context_process_key_event_async( |
| 418 context_focused_ ? context_ : fake_context_, | 411 context_, |
| 419 ibus_keyval, ibus_keycode, ibus_state, -1, NULL, | 412 ibus_keyval, ibus_keycode, ibus_state, -1, NULL, |
| 420 reinterpret_cast<GAsyncReadyCallback>(ProcessKeyEventDone), | 413 reinterpret_cast<GAsyncReadyCallback>(ProcessKeyEventDone), |
| 421 pending_key); | 414 pending_key); |
| 422 | 415 |
| 423 // We don't want to suppress the result generated by this key event, but it | 416 // We don't want to suppress the result generated by this key event, but it |
| 424 // may cause problem. See comment in ResetContext() method. | 417 // may cause problem. See comment in ResetContext() method. |
| 425 suppress_next_result_ = false; | 418 suppress_next_result_ = false; |
| 426 } | 419 } |
| 427 | 420 |
| 428 void InputMethodIBus::OnTextInputTypeChanged(View* view) { | 421 void InputMethodIBus::OnTextInputTypeChanged(View* view) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 UpdateContextFocusState(); | 491 UpdateContextFocusState(); |
| 499 | 492 |
| 500 // Force to update caret bounds, in case the View thinks that the caret | 493 // Force to update caret bounds, in case the View thinks that the caret |
| 501 // bounds has not changed. | 494 // bounds has not changed. |
| 502 if (context_focused_) | 495 if (context_focused_) |
| 503 OnCaretBoundsChanged(GetFocusedView()); | 496 OnCaretBoundsChanged(GetFocusedView()); |
| 504 } | 497 } |
| 505 | 498 |
| 506 void InputMethodIBus::CreateContext() { | 499 void InputMethodIBus::CreateContext() { |
| 507 DCHECK(!context_); | 500 DCHECK(!context_); |
| 508 DCHECK(!fake_context_); | |
| 509 DCHECK(GetIBus()); | 501 DCHECK(GetIBus()); |
| 510 DCHECK(ibus_bus_is_connected(GetIBus())); | 502 DCHECK(ibus_bus_is_connected(GetIBus())); |
| 511 DCHECK(!pending_create_ic_request_); | 503 DCHECK(!pending_create_ic_request_); |
| 512 DCHECK(!pending_create_fake_ic_request_); | |
| 513 | 504 |
| 514 // Creates the input context asynchronously. | 505 // Creates the input context asynchronously. |
| 515 pending_create_ic_request_ = new PendingCreateICRequest( | 506 pending_create_ic_request_ = new PendingCreateICRequest( |
| 516 this, &pending_create_ic_request_, false /* fake */); | 507 this, &pending_create_ic_request_); |
| 517 ibus_bus_create_input_context_async( | 508 ibus_bus_create_input_context_async( |
| 518 GetIBus(), "chrome", -1, NULL, | 509 GetIBus(), "chrome", -1, NULL, |
| 519 reinterpret_cast<GAsyncReadyCallback>(CreateInputContextDone), | 510 reinterpret_cast<GAsyncReadyCallback>(CreateInputContextDone), |
| 520 pending_create_ic_request_); | 511 pending_create_ic_request_); |
| 521 | |
| 522 // Creates the fake input context asynchronously. ibus will match the "fake" | |
| 523 // prefix in the application name to do magic thing. | |
| 524 pending_create_fake_ic_request_ = new PendingCreateICRequest( | |
| 525 this, &pending_create_fake_ic_request_, true /* fake */); | |
| 526 ibus_bus_create_input_context_async( | |
| 527 GetIBus(), "fake-chrome", -1, NULL, | |
| 528 reinterpret_cast<GAsyncReadyCallback>(CreateInputContextDone), | |
| 529 pending_create_fake_ic_request_); | |
| 530 } | 512 } |
| 531 | 513 |
| 532 void InputMethodIBus::SetContext(IBusInputContext* ic, bool fake) { | 514 void InputMethodIBus::SetContext(IBusInputContext* ic) { |
| 533 DCHECK(ic); | 515 DCHECK(ic); |
| 534 if (fake) { | |
| 535 DCHECK(!fake_context_); | |
| 536 fake_context_ = ic; | |
| 537 | |
| 538 // We only need to care about "destroy" signal of the fake context, | |
| 539 // as it will not generate any input method result. | |
| 540 g_signal_connect(ic, "destroy", G_CALLBACK(OnFakeDestroyThunk), this); | |
| 541 | |
| 542 ibus_input_context_set_capabilities(ic, IBUS_CAP_FOCUS); | |
| 543 UpdateFakeContextFocusState(); | |
| 544 return; | |
| 545 } | |
| 546 | |
| 547 DCHECK(!context_); | 516 DCHECK(!context_); |
| 548 context_ = ic; | 517 context_ = ic; |
| 549 | 518 |
| 550 // connect input context signals | 519 // connect input context signals |
| 551 g_signal_connect(ic, "commit-text", | 520 g_signal_connect(ic, "commit-text", |
| 552 G_CALLBACK(OnCommitTextThunk), this); | 521 G_CALLBACK(OnCommitTextThunk), this); |
| 553 g_signal_connect(ic, "forward-key-event", | 522 g_signal_connect(ic, "forward-key-event", |
| 554 G_CALLBACK(OnForwardKeyEventThunk), this); | 523 G_CALLBACK(OnForwardKeyEventThunk), this); |
| 555 g_signal_connect(ic, "update-preedit-text", | 524 g_signal_connect(ic, "update-preedit-text", |
| 556 G_CALLBACK(OnUpdatePreeditTextThunk), this); | 525 G_CALLBACK(OnUpdatePreeditTextThunk), this); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 575 // |pending_create_ic_request_| will be deleted in CreateInputContextDone(). | 544 // |pending_create_ic_request_| will be deleted in CreateInputContextDone(). |
| 576 pending_create_ic_request_->abandon(); | 545 pending_create_ic_request_->abandon(); |
| 577 pending_create_ic_request_ = NULL; | 546 pending_create_ic_request_ = NULL; |
| 578 } else if (context_) { | 547 } else if (context_) { |
| 579 // ibus_proxy_destroy() will not really release the resource of |context_| | 548 // ibus_proxy_destroy() will not really release the resource of |context_| |
| 580 // object. We still need to handle "destroy" signal and call | 549 // object. We still need to handle "destroy" signal and call |
| 581 // g_object_unref() there. | 550 // g_object_unref() there. |
| 582 ibus_proxy_destroy(reinterpret_cast<IBusProxy *>(context_)); | 551 ibus_proxy_destroy(reinterpret_cast<IBusProxy *>(context_)); |
| 583 DCHECK(!context_); | 552 DCHECK(!context_); |
| 584 } | 553 } |
| 585 | |
| 586 if (pending_create_fake_ic_request_) { | |
| 587 DCHECK(!fake_context_); | |
| 588 // |pending_create_fake_ic_request_| will be deleted in | |
| 589 // CreateInputContextDone(). | |
| 590 pending_create_fake_ic_request_->abandon(); | |
| 591 pending_create_fake_ic_request_ = NULL; | |
| 592 } else if (fake_context_) { | |
| 593 ibus_proxy_destroy(reinterpret_cast<IBusProxy *>(fake_context_)); | |
| 594 DCHECK(!fake_context_); | |
| 595 } | |
| 596 } | 554 } |
| 597 | 555 |
| 598 void InputMethodIBus::ConfirmCompositionText() { | 556 void InputMethodIBus::ConfirmCompositionText() { |
| 599 ui::TextInputClient* client = GetTextInputClient(); | 557 ui::TextInputClient* client = GetTextInputClient(); |
| 600 if (client && client->HasCompositionText()) | 558 if (client && client->HasCompositionText()) |
| 601 client->ConfirmCompositionText(); | 559 client->ConfirmCompositionText(); |
| 602 | 560 |
| 603 ResetContext(); | 561 ResetContext(); |
| 604 } | 562 } |
| 605 | 563 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 629 // is no reliable way to abandon all results generated by these abandoned key | 587 // is no reliable way to abandon all results generated by these abandoned key |
| 630 // events. | 588 // events. |
| 631 AbandonAllPendingKeyEvents(); | 589 AbandonAllPendingKeyEvents(); |
| 632 | 590 |
| 633 // This function runs asynchronously. | 591 // This function runs asynchronously. |
| 634 // Note: some input method engines may not support reset method, such as | 592 // Note: some input method engines may not support reset method, such as |
| 635 // ibus-anthy. But as we control all input method engines by ourselves, we can | 593 // ibus-anthy. But as we control all input method engines by ourselves, we can |
| 636 // make sure that all of the engines we are using support it correctly. | 594 // make sure that all of the engines we are using support it correctly. |
| 637 ibus_input_context_reset(context_); | 595 ibus_input_context_reset(context_); |
| 638 | 596 |
| 639 // We don't need to reset |fake_context_|. | |
| 640 | |
| 641 character_composer_.Reset(); | 597 character_composer_.Reset(); |
| 642 } | 598 } |
| 643 | 599 |
| 644 void InputMethodIBus::UpdateContextFocusState() { | 600 void InputMethodIBus::UpdateContextFocusState() { |
| 645 if (!context_) { | 601 if (!context_) { |
| 646 context_focused_ = false; | 602 context_focused_ = false; |
| 647 UpdateFakeContextFocusState(); | |
| 648 return; | 603 return; |
| 649 } | 604 } |
| 650 | 605 |
| 651 const bool old_context_focused = context_focused_; | 606 const bool old_context_focused = context_focused_; |
| 652 // Use switch here in case we are going to add more text input types. | 607 // Use switch here in case we are going to add more text input types. |
| 653 switch (GetTextInputType()) { | 608 switch (GetTextInputType()) { |
| 654 case ui::TEXT_INPUT_TYPE_NONE: | 609 case ui::TEXT_INPUT_TYPE_NONE: |
| 655 case ui::TEXT_INPUT_TYPE_PASSWORD: | 610 case ui::TEXT_INPUT_TYPE_PASSWORD: |
| 656 context_focused_ = false; | 611 context_focused_ = false; |
| 657 break; | 612 break; |
| 658 default: | 613 default: |
| 659 context_focused_ = true; | 614 context_focused_ = true; |
| 660 break; | 615 break; |
| 661 } | 616 } |
| 662 | 617 |
| 663 // We only focus in |context_| when the focus is in a normal textfield. | 618 // We only focus in |context_| when the focus is in a normal textfield. |
| 664 // ibus_input_context_focus_{in|out}() run asynchronously. | 619 // ibus_input_context_focus_{in|out}() run asynchronously. |
| 665 if (old_context_focused && !context_focused_) | 620 if (old_context_focused && !context_focused_) |
| 666 ibus_input_context_focus_out(context_); | 621 ibus_input_context_focus_out(context_); |
| 667 else if (!old_context_focused && context_focused_) | 622 else if (!old_context_focused && context_focused_) |
| 668 ibus_input_context_focus_in(context_); | 623 ibus_input_context_focus_in(context_); |
| 669 | |
| 670 UpdateFakeContextFocusState(); | |
| 671 } | |
| 672 | |
| 673 void InputMethodIBus::UpdateFakeContextFocusState() { | |
| 674 if (!fake_context_) | |
| 675 return; | |
| 676 | |
| 677 if (widget_focused() && !context_focused_ && | |
| 678 GetTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD) { | |
| 679 // We disable input method in password fields, so it makes no sense to allow | |
| 680 // switching input method. | |
| 681 ibus_input_context_focus_in(fake_context_); | |
| 682 } else { | |
| 683 ibus_input_context_focus_out(fake_context_); | |
| 684 } | |
| 685 } | 624 } |
| 686 | 625 |
| 687 void InputMethodIBus::ProcessKeyEventPostIME(const KeyEvent& key, | 626 void InputMethodIBus::ProcessKeyEventPostIME(const KeyEvent& key, |
| 688 guint32 ibus_keyval, | 627 guint32 ibus_keyval, |
| 689 bool handled) { | 628 bool handled) { |
| 690 // If we get here without a focused text input client, then it means the key | 629 // If we get here without a focused text input client, then it means the key |
| 691 // event is sent to the global ibus input context. | 630 // event is sent to the global ibus input context. |
| 692 if (!GetTextInputClient()) { | 631 if (!GetTextInputClient()) { |
| 693 DispatchKeyEventPostIME(key); | 632 DispatchKeyEventPostIME(key); |
| 694 return; | 633 return; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 context_focused_ = false; | 892 context_focused_ = false; |
| 954 | 893 |
| 955 ConfirmCompositionText(); | 894 ConfirmCompositionText(); |
| 956 | 895 |
| 957 // We are dead, so we need to ask the client to stop relying on us. | 896 // We are dead, so we need to ask the client to stop relying on us. |
| 958 // We cannot do it in DestroyContext(), because OnDestroy() may be called | 897 // We cannot do it in DestroyContext(), because OnDestroy() may be called |
| 959 // automatically. | 898 // automatically. |
| 960 OnInputMethodChanged(); | 899 OnInputMethodChanged(); |
| 961 } | 900 } |
| 962 | 901 |
| 963 void InputMethodIBus::OnFakeDestroy(IBusInputContext* context) { | |
| 964 DCHECK_EQ(fake_context_, context); | |
| 965 g_object_unref(fake_context_); | |
| 966 fake_context_ = NULL; | |
| 967 } | |
| 968 | |
| 969 void InputMethodIBus::OnIBusConnected(IBusBus* bus) { | 902 void InputMethodIBus::OnIBusConnected(IBusBus* bus) { |
| 970 DCHECK_EQ(GetIBus(), bus); | 903 DCHECK_EQ(GetIBus(), bus); |
| 971 DCHECK(ibus_bus_is_connected(bus)); | 904 DCHECK(ibus_bus_is_connected(bus)); |
| 972 | 905 |
| 973 DestroyContext(); | 906 DestroyContext(); |
| 974 CreateContext(); | 907 CreateContext(); |
| 975 } | 908 } |
| 976 | 909 |
| 977 void InputMethodIBus::OnIBusDisconnected(IBusBus* bus) { | 910 void InputMethodIBus::OnIBusDisconnected(IBusBus* bus) { |
| 978 DCHECK_EQ(GetIBus(), bus); | 911 DCHECK_EQ(GetIBus(), bus); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 995 } | 928 } |
| 996 return ibus; | 929 return ibus; |
| 997 } | 930 } |
| 998 | 931 |
| 999 // static | 932 // static |
| 1000 void InputMethodIBus::ProcessKeyEventDone(IBusInputContext* context, | 933 void InputMethodIBus::ProcessKeyEventDone(IBusInputContext* context, |
| 1001 GAsyncResult* res, | 934 GAsyncResult* res, |
| 1002 PendingKeyEvent* data) { | 935 PendingKeyEvent* data) { |
| 1003 DCHECK(data); | 936 DCHECK(data); |
| 1004 DCHECK(!data->input_method() || | 937 DCHECK(!data->input_method() || |
| 1005 data->input_method()->context_ == context || | 938 data->input_method()->context_ == context); |
| 1006 data->input_method()->fake_context_ == context); | |
| 1007 | 939 |
| 1008 gboolean handled = ibus_input_context_process_key_event_async_finish( | 940 gboolean handled = ibus_input_context_process_key_event_async_finish( |
| 1009 context, res, NULL); | 941 context, res, NULL); |
| 1010 data->ProcessPostIME(handled); | 942 data->ProcessPostIME(handled); |
| 1011 delete data; | 943 delete data; |
| 1012 } | 944 } |
| 1013 | 945 |
| 1014 // static | 946 // static |
| 1015 void InputMethodIBus::CreateInputContextDone(IBusBus* bus, | 947 void InputMethodIBus::CreateInputContextDone(IBusBus* bus, |
| 1016 GAsyncResult* res, | 948 GAsyncResult* res, |
| 1017 PendingCreateICRequest* data) { | 949 PendingCreateICRequest* data) { |
| 1018 DCHECK_EQ(GetIBus(), bus); | 950 DCHECK_EQ(GetIBus(), bus); |
| 1019 DCHECK(data); | 951 DCHECK(data); |
| 1020 IBusInputContext* ic = | 952 IBusInputContext* ic = |
| 1021 ibus_bus_create_input_context_async_finish(bus, res, NULL); | 953 ibus_bus_create_input_context_async_finish(bus, res, NULL); |
| 1022 if (ic) | 954 if (ic) |
| 1023 data->StoreOrAbandonInputContext(ic); | 955 data->StoreOrAbandonInputContext(ic); |
| 1024 delete data; | 956 delete data; |
| 1025 } | 957 } |
| 1026 | 958 |
| 1027 } // namespace views | 959 } // namespace views |
| OLD | NEW |