summaryrefslogtreecommitdiffstats
path: root/views/widget/widget_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'views/widget/widget_win.cc')
-rw-r--r--views/widget/widget_win.cc113
1 files changed, 102 insertions, 11 deletions
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc
index 0d6f47c..1cadfb1 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -23,9 +23,11 @@
#include "ui/gfx/path.h"
#include "views/accessibility/native_view_accessibility_win.h"
#include "views/controls/native_control_win.h"
+#include "views/controls/textfield/native_textfield_views.h"
#include "views/focus/accelerator_handler.h"
#include "views/focus/focus_util_win.h"
#include "views/focus/view_storage.h"
+#include "views/ime/input_method_win.h"
#include "views/views_delegate.h"
#include "views/widget/aero_tooltip_manager.h"
#include "views/widget/child_window_message_processor.h"
@@ -143,11 +145,15 @@ 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);
}
WidgetWin::~WidgetWin() {
+ // We need to delete the input method before calling DestroyRootView(),
+ // because it'll set focus_manager_ to NULL.
+ input_method_.reset();
DestroyRootView();
}
@@ -333,6 +339,19 @@ bool WidgetWin::HasMouseCapture() 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);
@@ -383,6 +402,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
@@ -620,6 +644,15 @@ 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() &&
+ NativeTextfieldViews::IsTextfieldViewsEnabled()) {
+ input_method_.reset(new InputMethodWin(this));
+ input_method_->Init(GetWidget());
+ is_input_method_win_ = true;
+ }
return 0;
}
@@ -699,6 +732,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);
}
@@ -709,28 +781,37 @@ 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 = { hwnd(), 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;
}
LRESULT WidgetWin::OnKeyUp(UINT message, WPARAM w_param, LPARAM l_param) {
- RootView* root_view = GetFocusedViewRootView();
- if (!root_view)
- root_view = GetRootView();
-
MSG msg = { hwnd(), 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 (input_method_.get())
+ input_method_->OnBlur();
SetMsgHandled(FALSE);
}
@@ -863,6 +944,8 @@ LRESULT WidgetWin::OnReflectedMessage(UINT msg,
void WidgetWin::OnSetFocus(HWND focused_window) {
delegate_->OnNativeFocus(focused_window);
+ if (input_method_.get())
+ input_method_->OnFocus();
SetMsgHandled(FALSE);
}
@@ -1057,6 +1140,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: