Index: views/widget/widget_win.cc |
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc |
index 2c247fd380b4f3ff3c3c59cd9fd8e00b277b5946..e0023a7d0c2fd96c4d7d8f6e756bd7517c4a4a8d 100644 |
--- a/views/widget/widget_win.cc |
+++ b/views/widget/widget_win.cc |
@@ -26,6 +26,7 @@ |
#include "views/focus/accelerator_handler.h" |
#include "views/focus/focus_util_win.h" |
#include "views/focus/view_storage.h" |
+#include "views/ime/input_method.h" |
#include "views/views_delegate.h" |
#include "views/widget/aero_tooltip_manager.h" |
#include "views/widget/child_window_message_processor.h" |
@@ -145,7 +146,8 @@ WidgetWin::WidgetWin() |
restore_focus_when_enabled_(false), |
accessibility_view_events_index_(-1), |
accessibility_view_events_(kMaxAccessibilityViewEvents), |
- previous_cursor_(NULL) { |
+ previous_cursor_(NULL), |
+ is_input_method_win_(false) { |
set_native_widget(this); |
} |
@@ -282,6 +284,19 @@ bool WidgetWin::HasNativeCapture() const { |
return GetCapture() == hwnd(); |
} |
+InputMethod* WidgetWin::GetInputMethodNative() { |
+ return input_method_.get(); |
+} |
+ |
+void WidgetWin::ReplaceInputMethod(InputMethod* input_method) { |
+ input_method_.reset(input_method); |
+ if (input_method) { |
+ input_method->set_delegate(this); |
+ input_method->Init(GetWidget()); |
+ } |
+ is_input_method_win_ = false; |
+} |
+ |
gfx::Rect WidgetWin::GetWindowScreenBounds() const { |
RECT r; |
GetWindowRect(&r); |
@@ -332,6 +347,11 @@ void WidgetWin::Close() { |
} |
void WidgetWin::CloseNow() { |
+ // Destroys the input method before closing the window so that it can be |
+ // detached from the widget correctly. |
+ input_method_.reset(); |
+ is_input_method_win_ = false; |
+ |
// We may already have been destroyed if the selection resulted in a tab |
// switch which will have reactivated the browser window and closed us, so |
// we need to check to see if we're still a window before trying to destroy |
@@ -571,6 +591,14 @@ LRESULT WidgetWin::OnCreate(CREATESTRUCT* create_struct) { |
ClientAreaSizeChanged(); |
delegate_->OnNativeWidgetCreated(); |
+ |
+ // delegate_->OnNativeWidgetCreated() creates the focus manager for top-level |
+ // widget. Only top-level widget should have an input method. |
+ if (delegate_->HasFocusManager()) { |
+ input_method_.reset(new InputMethodWin(this)); |
+ input_method_->Init(GetWidget()); |
+ is_input_method_win_ = true; |
+ } |
return 0; |
} |
@@ -650,6 +678,45 @@ void WidgetWin::OnHScroll(int scroll_type, short position, HWND scrollbar) { |
SetMsgHandled(FALSE); |
} |
+LRESULT WidgetWin::OnImeMessages(UINT message, WPARAM w_param, LPARAM l_param) { |
+ if (!is_input_method_win_) { |
+ SetMsgHandled(FALSE); |
+ return 0; |
+ } |
+ |
+ InputMethodWin* ime = static_cast<InputMethodWin*>(input_method_.get()); |
+ BOOL handled = FALSE; |
+ LRESULT result = 0; |
+ switch (message) { |
+ case WM_IME_SETCONTEXT: |
+ result = ime->OnImeSetContext(message, w_param, l_param, &handled); |
+ break; |
+ case WM_IME_STARTCOMPOSITION: |
+ result = ime->OnImeStartComposition(message, w_param, l_param, &handled); |
+ break; |
+ case WM_IME_COMPOSITION: |
+ result = ime->OnImeComposition(message, w_param, l_param, &handled); |
+ break; |
+ case WM_IME_ENDCOMPOSITION: |
+ result = ime->OnImeEndComposition(message, w_param, l_param, &handled); |
+ break; |
+ case WM_CHAR: |
+ case WM_SYSCHAR: |
+ result = ime->OnChar(message, w_param, l_param, &handled); |
+ break; |
+ case WM_DEADCHAR: |
+ case WM_SYSDEADCHAR: |
+ result = ime->OnDeadChar(message, w_param, l_param, &handled); |
+ break; |
+ default: |
+ NOTREACHED() << "Unknown IME message:" << message; |
+ break; |
+ } |
+ |
+ SetMsgHandled(handled); |
+ return result; |
+} |
+ |
void WidgetWin::OnInitMenu(HMENU menu) { |
SetMsgHandled(FALSE); |
} |
@@ -660,30 +727,39 @@ void WidgetWin::OnInitMenuPopup(HMENU menu, |
SetMsgHandled(FALSE); |
} |
-LRESULT WidgetWin::OnKeyDown(UINT message, WPARAM w_param, LPARAM l_param) { |
- RootView* root_view = GetFocusedViewRootView(); |
- if (!root_view) |
- root_view = GetRootView(); |
+void WidgetWin::OnInputLangChange(DWORD character_set, HKL input_language_id) { |
+ if (is_input_method_win_) { |
+ static_cast<InputMethodWin*>(input_method_.get())->OnInputLangChange( |
+ character_set, input_language_id); |
+ } |
+} |
+LRESULT WidgetWin::OnKeyDown(UINT message, WPARAM w_param, LPARAM l_param) { |
MSG msg; |
MakeMSG(&msg, message, w_param, l_param); |
- SetMsgHandled(root_view->ProcessKeyEvent(KeyEvent(msg))); |
+ KeyEvent key(msg); |
+ if (input_method_.get()) |
+ input_method_->DispatchKeyEvent(key); |
+ else |
+ DispatchKeyEventPostIME(key); |
sadrul
2011/03/21 19:57:45
Instead of DispatchKeyEvent'ing here (and OnKeyUp,
James Su
2011/03/21 21:34:07
It's not possible. The native widget may still nee
|
return 0; |
} |
LRESULT WidgetWin::OnKeyUp(UINT message, WPARAM w_param, LPARAM l_param) { |
- RootView* root_view = GetFocusedViewRootView(); |
- if (!root_view) |
- root_view = GetRootView(); |
- |
MSG msg; |
MakeMSG(&msg, message, w_param, l_param); |
- SetMsgHandled(root_view->ProcessKeyEvent(KeyEvent(msg))); |
+ KeyEvent key(msg); |
+ if (input_method_.get()) |
+ input_method_->DispatchKeyEvent(key); |
+ else |
+ DispatchKeyEventPostIME(key); |
return 0; |
} |
void WidgetWin::OnKillFocus(HWND focused_window) { |
delegate_->OnNativeBlur(focused_window); |
+ if (is_input_method_win_) |
+ static_cast<InputMethodWin*>(input_method_.get())->OnKillFocus(); |
SetMsgHandled(FALSE); |
} |
@@ -861,6 +937,8 @@ LRESULT WidgetWin::OnReflectedMessage(UINT msg, |
void WidgetWin::OnSetFocus(HWND focused_window) { |
delegate_->OnNativeFocus(focused_window); |
+ if (is_input_method_win_) |
+ static_cast<InputMethodWin*>(input_method_.get())->OnSetFocus(); |
SetMsgHandled(FALSE); |
} |
@@ -1143,6 +1221,14 @@ gfx::AcceleratedWidget WidgetWin::GetAcceleratedWidget() { |
return gfx::kNullAcceleratedWidget; |
} |
+void WidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { |
+ RootView* root_view = GetFocusedViewRootView(); |
+ if (!root_view) |
+ root_view = GetRootView(); |
+ |
+ SetMsgHandled(root_view->ProcessKeyEvent(key)); |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// Widget, public: |