summaryrefslogtreecommitdiffstats
path: root/views/widget
diff options
context:
space:
mode:
authoroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-23 05:01:35 +0000
committeroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-23 05:01:35 +0000
commit2bd4b68de2e193aca51caa09edddb8fd0cd3b9cd (patch)
tree46164cc11e0396a66286f29ed4cb99e044583f19 /views/widget
parentd776fbf0f45a3d435449740b1c8973b8866231fa (diff)
downloadchromium_src-2bd4b68de2e193aca51caa09edddb8fd0cd3b9cd.zip
chromium_src-2bd4b68de2e193aca51caa09edddb8fd0cd3b9cd.tar.gz
chromium_src-2bd4b68de2e193aca51caa09edddb8fd0cd3b9cd.tar.bz2
Move input_method to widget
BUG=none TEST=none. no new functionality. all tests should pass. Review URL: http://codereview.chromium.org/7371007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97819 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/widget')
-rw-r--r--views/widget/native_widget_delegate.h7
-rw-r--r--views/widget/native_widget_gtk.cc57
-rw-r--r--views/widget/native_widget_gtk.h9
-rw-r--r--views/widget/native_widget_private.h10
-rw-r--r--views/widget/native_widget_views.cc46
-rw-r--r--views/widget/native_widget_views.h9
-rw-r--r--views/widget/native_widget_win.cc95
-rw-r--r--views/widget/native_widget_win.h12
-rw-r--r--views/widget/widget.cc61
-rw-r--r--views/widget/widget.h36
10 files changed, 154 insertions, 188 deletions
diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h
index bfd0705..95d2aa1 100644
--- a/views/widget/native_widget_delegate.h
+++ b/views/widget/native_widget_delegate.h
@@ -20,6 +20,8 @@ enum TouchStatus;
#endif
namespace views {
+class InputMethod;
+
namespace internal {
////////////////////////////////////////////////////////////////////////////////
@@ -99,6 +101,11 @@ class VIEWS_EXPORT NativeWidgetDelegate {
// Runs the specified native command. Returns true if the command is handled.
virtual bool ExecuteCommand(int command_id) = 0;
+ // Returns the input method of the widget this delegate is associated with.
+ // Note that this does not use the top level widget, so may return NULL
+ // if the widget doesn't have input method.
+ virtual InputMethod* GetInputMethodDirect() = 0;
+
//
virtual Widget* AsWidget() = 0;
virtual const Widget* AsWidget() const = 0;
diff --git a/views/widget/native_widget_gtk.cc b/views/widget/native_widget_gtk.cc
index a57da4a..8081a31 100644
--- a/views/widget/native_widget_gtk.cc
+++ b/views/widget/native_widget_gtk.cc
@@ -393,7 +393,6 @@ NativeWidgetGtk::NativeWidgetGtk(internal::NativeWidgetDelegate* delegate)
NativeWidgetGtk::~NativeWidgetGtk() {
// We need to delete the input method before calling DestroyRootView(),
// because it'll set focus_manager_ to NULL.
- input_method_.reset();
if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) {
DCHECK(widget_ == NULL);
delete delegate_;
@@ -961,33 +960,21 @@ bool NativeWidgetGtk::HasMouseCapture() const {
return GTK_WIDGET_HAS_GRAB(window_contents_) || has_pointer_grab_;
}
-InputMethod* NativeWidgetGtk::GetInputMethodNative() {
- if (!input_method_.get()) {
- // Create input method when it is requested by a child view.
- // TODO(suzhe): Always enable input method when we start to use
- // RenderWidgetHostViewViews in normal ChromeOS.
- if (!child_ && views::Widget::IsPureViews()) {
+InputMethod* NativeWidgetGtk::CreateInputMethod() {
+ // Create input method when pure views is enabled.
+ // TODO(suzhe): Always enable input method when we start to use
+ // RenderWidgetHostViewViews in normal ChromeOS.
+ if (views::Widget::IsPureViews()) {
#if defined(HAVE_IBUS)
- input_method_.reset(InputMethodIBus::IsInputMethodIBusEnabled() ?
- static_cast<InputMethod*>(new InputMethodIBus(this)) :
- static_cast<InputMethod*>(new InputMethodGtk(this)));
+ return InputMethodIBus::IsInputMethodIBusEnabled() ?
+ static_cast<InputMethod*>(new InputMethodIBus(this)) :
+ static_cast<InputMethod*>(new InputMethodGtk(this));
#else
- input_method_.reset(new InputMethodGtk(this));
+ return new InputMethodGtk(this);
#endif
- input_method_->Init(GetWidget());
- if (has_focus_)
- input_method_->OnFocus();
- }
- }
- return input_method_.get();
-}
-
-void NativeWidgetGtk::ReplaceInputMethod(InputMethod* input_method) {
- input_method_.reset(input_method);
- if (input_method) {
- input_method->set_delegate(this);
- input_method->Init(GetWidget());
}
+ // GTK's textfield handles IME.
+ return NULL;
}
void NativeWidgetGtk::CenterWindow(const gfx::Size& size) {
@@ -1163,7 +1150,6 @@ void NativeWidgetGtk::Close() {
void NativeWidgetGtk::CloseNow() {
if (widget_) {
- input_method_.reset();
gtk_widget_destroy(widget_); // Triggers OnDestroy().
}
}
@@ -1648,12 +1634,13 @@ gboolean NativeWidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) {
should_handle_menu_key_release_ = false;
- if (child_)
+ if (!GetWidget()->is_top_level())
return false;
// Only top-level Widget should have an InputMethod instance.
- if (input_method_.get())
- input_method_->OnFocus();
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+ if (input_method)
+ input_method->OnFocus();
// See description of got_initial_focus_in_ for details on this.
if (!got_initial_focus_in_) {
@@ -1671,19 +1658,21 @@ gboolean NativeWidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) {
return false; // This is the second focus-out event in a row, ignore it.
has_focus_ = false;
- if (child_)
+ if (GetWidget()->is_top_level())
return false;
// Only top-level Widget should have an InputMethod instance.
- if (input_method_.get())
- input_method_->OnBlur();
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+ if (input_method)
+ input_method->OnBlur();
return false;
}
gboolean NativeWidgetGtk::OnEventKey(GtkWidget* widget, GdkEventKey* event) {
KeyEvent key(reinterpret_cast<NativeEvent>(event));
- if (input_method_.get())
- input_method_->DispatchKeyEvent(key);
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+ if (input_method)
+ input_method->DispatchKeyEvent(key);
else
DispatchKeyEventPostIME(key);
@@ -2192,7 +2181,7 @@ NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
parent_gtkwidget = gtk_widget_get_parent(parent_gtkwidget);
} while (parent_gtkwidget);
- return widget;
+ return widget && widget->GetWidget()->is_top_level() ? widget : NULL;
}
// static
diff --git a/views/widget/native_widget_gtk.h b/views/widget/native_widget_gtk.h
index 051e40c..659db5f 100644
--- a/views/widget/native_widget_gtk.h
+++ b/views/widget/native_widget_gtk.h
@@ -14,7 +14,6 @@
#include "ui/base/x/active_window_watcher_x.h"
#include "ui/gfx/size.h"
#include "views/focus/focus_manager.h"
-#include "views/ime/input_method_delegate.h"
#include "views/widget/native_widget_private.h"
#include "views/widget/widget.h"
@@ -42,8 +41,7 @@ class NativeWidgetDelegate;
// Widget implementation for GTK.
class VIEWS_EXPORT NativeWidgetGtk : public internal::NativeWidgetPrivate,
- public ui::ActiveWindowWatcherX::Observer,
- public internal::InputMethodDelegate {
+ public ui::ActiveWindowWatcherX::Observer {
public:
explicit NativeWidgetGtk(internal::NativeWidgetDelegate* delegate);
virtual ~NativeWidgetGtk();
@@ -166,8 +164,7 @@ class VIEWS_EXPORT NativeWidgetGtk : public internal::NativeWidgetPrivate,
virtual void SetMouseCapture() OVERRIDE;
virtual void ReleaseMouseCapture() OVERRIDE;
virtual bool HasMouseCapture() const OVERRIDE;
- virtual InputMethod* GetInputMethodNative() OVERRIDE;
- virtual void ReplaceInputMethod(InputMethod* input_method) OVERRIDE;
+ virtual InputMethod* CreateInputMethod() OVERRIDE;
virtual void CenterWindow(const gfx::Size& size) OVERRIDE;
virtual void GetWindowBoundsAndMaximizedState(gfx::Rect* bounds,
bool* maximized) const OVERRIDE;
@@ -434,8 +431,6 @@ class VIEWS_EXPORT NativeWidgetGtk : public internal::NativeWidgetPrivate,
// that window manager shows the window only after the window is painted.
bool painted_;
- scoped_ptr<InputMethod> input_method_;
-
// The compositor for accelerated drawing.
scoped_refptr<ui::Compositor> compositor_;
diff --git a/views/widget/native_widget_private.h b/views/widget/native_widget_private.h
index 3c31663..df332cf 100644
--- a/views/widget/native_widget_private.h
+++ b/views/widget/native_widget_private.h
@@ -7,6 +7,7 @@
#pragma once
#include "ui/gfx/native_widget_types.h"
+#include "views/ime/input_method_delegate.h"
#include "views/widget/native_widget.h"
namespace gfx {
@@ -36,7 +37,8 @@ namespace internal {
// NativeWidget implementations. This file should not be included
// in code that does not fall into one of these use cases.
//
-class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget {
+class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget,
+ public internal::InputMethodDelegate {
public:
virtual ~NativeWidgetPrivate() {}
@@ -129,12 +131,8 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget {
// Note that all widgets in a widget hierarchy share the same input method.
// TODO(suzhe): rename to GetInputMethod() when NativeWidget implementation
// class doesn't inherit Widget anymore.
- virtual InputMethod* GetInputMethodNative() = 0;
+ virtual InputMethod* CreateInputMethod() = 0;
- // Sets a different InputMethod instance to this native widget. The instance
- // must not be initialized, the ownership will be assumed by the native
- // widget. It's only for testing purpose.
- virtual void ReplaceInputMethod(InputMethod* input_method) = 0;
// Centers the window and sizes it to the specified size.
virtual void CenterWindow(const gfx::Size& size) = 0;
diff --git a/views/widget/native_widget_views.cc b/views/widget/native_widget_views.cc
index ebb141e..5fc8721 100644
--- a/views/widget/native_widget_views.cc
+++ b/views/widget/native_widget_views.cc
@@ -57,26 +57,33 @@ const View* NativeWidgetViews::GetView() const {
}
void NativeWidgetViews::OnActivate(bool active) {
+ // TODO(oshima): find out if we should check toplevel here.
if (active_ == active)
return;
active_ = active;
delegate_->OnNativeWidgetActivationChanged(active);
- InputMethod* input_method = GetInputMethodNative();
+
// TODO(oshima): Focus change should be separated from window activation.
// This will be fixed when we have WM API.
- if (active) {
- input_method->OnFocus();
- // See description of got_initial_focus_in_ for details on this.
- GetWidget()->GetFocusManager()->RestoreFocusedView();
- } else {
- input_method->OnBlur();
- GetWidget()->GetFocusManager()->StoreFocusedView();
+ Widget* widget = GetWidget();
+ if (widget->is_top_level()) {
+ InputMethod* input_method = widget->GetInputMethodDirect();
+ if (active) {
+ input_method->OnFocus();
+ // See description of got_initial_focus_in_ for details on this.
+ widget->GetFocusManager()->RestoreFocusedView();
+ } else {
+ input_method->OnBlur();
+ widget->GetFocusManager()->StoreFocusedView();
+ }
}
view_->SchedulePaint();
}
bool NativeWidgetViews::OnKeyEvent(const KeyEvent& key_event) {
- GetInputMethodNative()->DispatchKeyEvent(key_event);
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+ DCHECK(input_method);
+ input_method->DispatchKeyEvent(key_event);
return true;
}
@@ -227,24 +234,12 @@ bool NativeWidgetViews::HasMouseCapture() const {
return WindowManager::Get()->HasMouseCapture(GetWidget());
}
-InputMethod* NativeWidgetViews::GetInputMethodNative() {
- if (!input_method_.get()) {
+InputMethod* NativeWidgetViews::CreateInputMethod() {
#if defined(HAVE_IBUS)
- input_method_.reset(static_cast<InputMethod*>(new InputMethodIBus(this)));
+ return new InputMethodIBus(this);
#else
- // TODO(suzhe|oshima): Figure out what to do on windows.
- input_method_.reset(new MockInputMethod(this));
+ return new MockInputMethod(this);
#endif
- input_method_->Init(GetWidget());
- }
- return input_method_.get();
-}
-
-void NativeWidgetViews::ReplaceInputMethod(InputMethod* input_method) {
- CHECK(input_method);
- input_method_.reset(input_method);
- input_method->set_delegate(this);
- input_method->Init(GetWidget());
}
void NativeWidgetViews::CenterWindow(const gfx::Size& size) {
@@ -334,9 +329,6 @@ void NativeWidgetViews::Close() {
}
void NativeWidgetViews::CloseNow() {
- // reset input_method before destroying widget.
- input_method_.reset();
-
delete view_;
view_ = NULL;
}
diff --git a/views/widget/native_widget_views.h b/views/widget/native_widget_views.h
index 1b4ad7d..440600c 100644
--- a/views/widget/native_widget_views.h
+++ b/views/widget/native_widget_views.h
@@ -10,7 +10,6 @@
#include "base/message_loop.h"
#include "ui/gfx/transform.h"
-#include "views/ime/input_method_delegate.h"
#include "views/widget/native_widget_private.h"
namespace views {
@@ -27,8 +26,7 @@ class NativeWidgetView;
//
// A NativeWidget implementation that uses another View as its native widget.
//
-class VIEWS_EXPORT NativeWidgetViews : public internal::NativeWidgetPrivate,
- public internal::InputMethodDelegate {
+class VIEWS_EXPORT NativeWidgetViews : public internal::NativeWidgetPrivate {
public:
explicit NativeWidgetViews(internal::NativeWidgetDelegate* delegate);
virtual ~NativeWidgetViews();
@@ -77,8 +75,7 @@ class VIEWS_EXPORT NativeWidgetViews : public internal::NativeWidgetPrivate,
virtual void SetMouseCapture() OVERRIDE;
virtual void ReleaseMouseCapture() OVERRIDE;
virtual bool HasMouseCapture() const OVERRIDE;
- virtual InputMethod* GetInputMethodNative() OVERRIDE;
- virtual void ReplaceInputMethod(InputMethod* input_method) OVERRIDE;
+ virtual InputMethod* CreateInputMethod() OVERRIDE;
virtual void CenterWindow(const gfx::Size& size) OVERRIDE;
virtual void GetWindowBoundsAndMaximizedState(gfx::Rect* bounds,
bool* maximized) const OVERRIDE;
@@ -164,8 +161,6 @@ class VIEWS_EXPORT NativeWidgetViews : public internal::NativeWidgetPrivate,
bool delete_native_view_;
- scoped_ptr<InputMethod> input_method_;
-
std::map<const char*, void*> window_properties_;
DISALLOW_COPY_AND_ASSIGN(NativeWidgetViews);
diff --git a/views/widget/native_widget_win.cc b/views/widget/native_widget_win.cc
index e7f1ebd..16fca92 100644
--- a/views/widget/native_widget_win.cc
+++ b/views/widget/native_widget_win.cc
@@ -373,7 +373,6 @@ NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate)
accessibility_view_events_index_(-1),
accessibility_view_events_(kMaxAccessibilityViewEvents),
previous_cursor_(NULL),
- is_input_method_win_(false),
fullscreen_(false),
force_hidden_count_(0),
lock_updates_(false),
@@ -386,9 +385,6 @@ NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate)
}
NativeWidgetWin::~NativeWidgetWin() {
- // We need to delete the input method before calling DestroyRootView(),
- // because it'll set focus_manager_ to NULL.
- input_method_.reset();
if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
delete delegate_;
else
@@ -625,17 +621,8 @@ bool NativeWidgetWin::HasMouseCapture() const {
return GetCapture() == hwnd();
}
-InputMethod* NativeWidgetWin::GetInputMethodNative() {
- return input_method_.get();
-}
-
-void NativeWidgetWin::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;
+InputMethod* NativeWidgetWin::CreateInputMethod() {
+ return views::Widget::IsPureViews() ? new InputMethodWin(this) : NULL;
}
void NativeWidgetWin::CenterWindow(const gfx::Size& size) {
@@ -841,11 +828,6 @@ void NativeWidgetWin::Close() {
}
void NativeWidgetWin::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
@@ -1133,9 +1115,14 @@ LRESULT NativeWidgetWin::OnWndProc(UINT message, WPARAM w_param,
MessageLoopForUI::current()->RemoveObserver(this);
OnFinalMessage(window);
}
- if (message == WM_ACTIVATE)
+
+ // Only top level widget should store/restore focus.
+ if (message == WM_ACTIVATE && GetWidget()->is_top_level())
PostProcessActivateMessage(this, LOWORD(w_param));
if (message == WM_ENABLE && restore_focus_when_enabled_) {
+ // This path should be executed only for top level as
+ // restore_focus_when_enabled_ is set in PostProcessActivateMessage.
+ DCHECK(GetWidget()->is_top_level());
restore_focus_when_enabled_ = false;
GetWidget()->GetFocusManager()->RestoreFocusedView();
}
@@ -1266,14 +1253,6 @@ LRESULT NativeWidgetWin::OnCreate(CREATESTRUCT* create_struct) {
delegate_->OnNativeWidgetCreated();
- // delegate_->OnNativeWidgetCreated() creates the focus manager for top-level
- // widget. Only top-level widget should have an input method.
- if (delegate_->HasFocusManager() && views::Widget::IsPureViews()) {
- input_method_.reset(new InputMethodWin(this));
- input_method_->Init(GetWidget());
- is_input_method_win_ = true;
- }
-
// Get access to a modifiable copy of the system menu.
GetSystemMenu(hwnd(), false);
return 0;
@@ -1388,39 +1367,15 @@ void NativeWidgetWin::OnHScroll(int scroll_type,
LRESULT NativeWidgetWin::OnImeMessages(UINT message,
WPARAM w_param,
LPARAM l_param) {
- if (!is_input_method_win_) {
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+ if (!input_method || input_method->IsMock()) {
SetMsgHandled(FALSE);
return 0;
}
- InputMethodWin* ime = static_cast<InputMethodWin*>(input_method_.get());
+ InputMethodWin* ime_win = static_cast<InputMethodWin*>(input_method);
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;
- }
+ LRESULT result = ime_win->OnImeMessages(message, w_param, l_param, &handled);
SetMsgHandled(handled);
return result;
@@ -1453,8 +1408,10 @@ void NativeWidgetWin::OnInitMenuPopup(HMENU menu,
void NativeWidgetWin::OnInputLangChange(DWORD character_set,
HKL input_language_id) {
- if (is_input_method_win_) {
- static_cast<InputMethodWin*>(input_method_.get())->OnInputLangChange(
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+
+ if (input_method && !input_method->IsMock()) {
+ static_cast<InputMethodWin*>(input_method)->OnInputLangChange(
character_set, input_language_id);
}
}
@@ -1464,8 +1421,9 @@ LRESULT NativeWidgetWin::OnKeyEvent(UINT message,
LPARAM l_param) {
MSG msg = { hwnd(), message, w_param, l_param };
KeyEvent key(msg);
- if (input_method_.get())
- input_method_->DispatchKeyEvent(key);
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+ if (input_method)
+ input_method->DispatchKeyEvent(key);
else
DispatchKeyEventPostIME(key);
return 0;
@@ -1473,8 +1431,9 @@ LRESULT NativeWidgetWin::OnKeyEvent(UINT message,
void NativeWidgetWin::OnKillFocus(HWND focused_window) {
delegate_->OnNativeBlur(focused_window);
- if (input_method_.get())
- input_method_->OnBlur();
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+ if (input_method)
+ input_method->OnBlur();
SetMsgHandled(FALSE);
}
@@ -1901,8 +1860,9 @@ LRESULT NativeWidgetWin::OnSetCursor(UINT message,
void NativeWidgetWin::OnSetFocus(HWND focused_window) {
delegate_->OnNativeFocus(focused_window);
- if (input_method_.get())
- input_method_->OnFocus();
+ InputMethod* input_method = GetWidget()->GetInputMethodDirect();
+ if (input_method)
+ input_method->OnFocus();
SetMsgHandled(FALSE);
}
@@ -2172,10 +2132,7 @@ void NativeWidgetWin::ExecuteSystemMenuCommand(int command) {
// static
void NativeWidgetWin::PostProcessActivateMessage(NativeWidgetWin* widget,
int activation_state) {
- if (!widget->delegate_->HasFocusManager()) {
- NOTREACHED();
- return;
- }
+ DCHECK(widget->GetWidget()->is_top_level());
FocusManager* focus_manager = widget->GetWidget()->GetFocusManager();
if (WA_INACTIVE == activation_state) {
// We might get activated/inactivated without being enabled, so we need to
diff --git a/views/widget/native_widget_win.h b/views/widget/native_widget_win.h
index 1525de7..9aef85d 100644
--- a/views/widget/native_widget_win.h
+++ b/views/widget/native_widget_win.h
@@ -21,7 +21,6 @@
#include "base/win/scoped_comptr.h"
#include "ui/base/win/window_impl.h"
#include "views/focus/focus_manager.h"
-#include "views/ime/input_method_delegate.h"
#include "views/layout/layout_manager.h"
#include "views/widget/native_widget_private.h"
@@ -86,9 +85,8 @@ const int WM_NCUAHDRAWFRAME = 0xAF;
//
///////////////////////////////////////////////////////////////////////////////
class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl,
- public internal::NativeWidgetPrivate,
public MessageLoopForUI::Observer,
- public internal::InputMethodDelegate {
+ public internal::NativeWidgetPrivate {
public:
explicit NativeWidgetWin(internal::NativeWidgetDelegate* delegate);
virtual ~NativeWidgetWin();
@@ -216,8 +214,7 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl,
virtual void SetMouseCapture() OVERRIDE;
virtual void ReleaseMouseCapture() OVERRIDE;
virtual bool HasMouseCapture() const OVERRIDE;
- virtual InputMethod* GetInputMethodNative() OVERRIDE;
- virtual void ReplaceInputMethod(InputMethod* input_method) OVERRIDE;
+ virtual InputMethod* CreateInputMethod() OVERRIDE;
virtual void CenterWindow(const gfx::Size& size) OVERRIDE;
virtual void GetWindowBoundsAndMaximizedState(gfx::Rect* bounds,
bool* maximized) const OVERRIDE;
@@ -610,11 +607,6 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl,
ViewProps props_;
- scoped_ptr<InputMethod> input_method_;
-
- // Indicates if the |input_method_| is an InputMethodWin instance.
- bool is_input_method_win_;
-
// True if we're in fullscreen mode.
bool fullscreen_;
diff --git a/views/widget/widget.cc b/views/widget/widget.cc
index 691ab97..eb7c0d1 100644
--- a/views/widget/widget.cc
+++ b/views/widget/widget.cc
@@ -11,6 +11,7 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/compositor/compositor.h"
#include "views/controls/menu/menu_controller.h"
+#include "views/focus/focus_manager_factory.h"
#include "views/focus/view_storage.h"
#include "views/ime/input_method.h"
#include "views/views_delegate.h"
@@ -104,7 +105,8 @@ Widget::InitParams::InitParams()
double_buffer(false),
parent(NULL),
parent_widget(NULL),
- native_widget(NULL) {
+ native_widget(NULL),
+ top_level(false) {
}
Widget::InitParams::InitParams(Type type)
@@ -123,7 +125,8 @@ Widget::InitParams::InitParams(Type type)
double_buffer(false),
parent(NULL),
parent_widget(NULL),
- native_widget(NULL) {
+ native_widget(NULL),
+ top_level(false) {
}
////////////////////////////////////////////////////////////////////////////////
@@ -149,7 +152,8 @@ Widget::Widget()
widget_closed_(false),
saved_maximized_state_(false),
minimum_size_(100, 100),
- focus_on_creation_(true) {
+ focus_on_creation_(true),
+ is_top_level_(false) {
}
Widget::~Widget() {
@@ -159,7 +163,6 @@ Widget::~Widget() {
}
DestroyRootView();
-
if (ownership_ == InitParams::WIDGET_OWNS_NATIVE_WIDGET)
delete native_widget_;
}
@@ -275,6 +278,10 @@ bool Widget::IsDebugPaintEnabled() {
}
void Widget::Init(const InitParams& params) {
+ is_top_level_ = params.top_level ||
+ (!params.child &&
+ params.type != InitParams::TYPE_CONTROL &&
+ params.type != InitParams::TYPE_TOOLTIP);
widget_delegate_ =
params.delegate ? params.delegate : new DefaultWidgetDelegate(this);
ownership_ = params.ownership;
@@ -361,6 +368,12 @@ Widget* Widget::GetTopLevelWidget() {
}
const Widget* Widget::GetTopLevelWidget() const {
+ // GetTopLevelNativeWidget doesn't work during destruction because
+ // property is gone after gobject gets deleted. Short circuit here
+ // for toplevel so that InputMethod can remove itself from
+ // focus manager.
+ if (is_top_level())
+ return this;
return native_widget_->GetTopLevelWidget();
}
@@ -432,7 +445,7 @@ void Widget::Close() {
// |FormManager::ViewRemoved()| calls are fouled. We clear focus here
// to avoid these redundant steps and to avoid accessing deleted views
// that may have been in focus.
- if (GetTopLevelWidget() == this && focus_manager_.get())
+ if (is_top_level() && focus_manager_.get())
focus_manager_->SetFocusedView(NULL);
native_widget_->Close();
@@ -579,16 +592,12 @@ ThemeProvider* Widget::GetThemeProvider() const {
FocusManager* Widget::GetFocusManager() {
Widget* toplevel_widget = GetTopLevelWidget();
- if (toplevel_widget && toplevel_widget != this)
- return toplevel_widget->focus_manager_.get();
-
- return focus_manager_.get();
+ return toplevel_widget ? toplevel_widget->focus_manager_.get() : NULL;
}
InputMethod* Widget::GetInputMethod() {
Widget* toplevel_widget = GetTopLevelWidget();
- return toplevel_widget ?
- toplevel_widget->native_widget_->GetInputMethodNative() : NULL;
+ return toplevel_widget ? toplevel_widget->GetInputMethodDirect() : NULL;
}
void Widget::RunShellDrag(View* view, const ui::OSExchangeData& data,
@@ -832,11 +841,8 @@ void Widget::OnNativeWidgetVisibilityChanged(bool visible) {
}
void Widget::OnNativeWidgetCreated() {
- if (GetTopLevelWidget() == this) {
- // Only the top level Widget in a native widget hierarchy has a focus
- // manager.
- focus_manager_.reset(new FocusManager(this));
- }
+ if (is_top_level())
+ focus_manager_.reset(FocusManagerFactory::Create(this));
native_widget_->SetAccessibleRole(
widget_delegate_->GetAccessibleWindowRole());
@@ -968,6 +974,12 @@ bool Widget::ExecuteCommand(int command_id) {
return widget_delegate_->ExecuteWindowsCommand(command_id);
}
+InputMethod* Widget::GetInputMethodDirect() {
+ if (!input_method_.get() && is_top_level())
+ ReplaceInputMethod(native_widget_->CreateInputMethod());
+ return input_method_.get();
+}
+
Widget* Widget::AsWidget() {
return this;
}
@@ -1006,7 +1018,8 @@ internal::RootView* Widget::CreateRootView() {
void Widget::DestroyRootView() {
root_view_.reset();
-
+ // Input method has to be destroyed before focus manager.
+ input_method_.reset();
// Defer focus manager's destruction. This is for the case when the
// focus manager is referenced by a child NativeWidgetGtk (e.g. TabbedPane in
// a dialog). When gtk_widget_destroy is called on the parent, the destroy
@@ -1019,10 +1032,6 @@ void Widget::DestroyRootView() {
MessageLoop::current()->DeleteSoon(FROM_HERE, focus_manager);
}
-void Widget::ReplaceFocusManager(FocusManager* focus_manager) {
- focus_manager_.reset(focus_manager);
-}
-
////////////////////////////////////////////////////////////////////////////////
// Widget, private:
@@ -1098,6 +1107,16 @@ bool Widget::GetSavedBounds(gfx::Rect* bounds, bool* maximize) {
return false;
}
+void Widget::ReplaceInputMethod(InputMethod* input_method) {
+ input_method_.reset(input_method);
+ // TODO(oshima): Gtk's textfield doesn't need views InputMethod.
+ // Remove this check once gtk is removed.
+ if (input_method) {
+ input_method->set_delegate(native_widget_);
+ input_method->Init(this);
+ }
+}
+
namespace internal {
////////////////////////////////////////////////////////////////////////////////
diff --git a/views/widget/widget.h b/views/widget/widget.h
index 4827eae..a85b619 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -8,6 +8,7 @@
#include <stack>
+#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "ui/base/accessibility/accessibility_types.h"
@@ -155,6 +156,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// When set, this value is used as the Widget's NativeWidget implementation.
// The Widget will not construct a default one. Default is NULL.
NativeWidget* native_widget;
+ bool top_level;
};
static InitParams WindowInitParams();
@@ -198,8 +200,11 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
static Widget* GetWidgetForNativeView(gfx::NativeView native_view);
static Widget* GetWidgetForNativeWindow(gfx::NativeWindow native_window);
- // Retrieves the highest Widget in a native view hierarchy starting at
- // |native_view|, which may or may not be a Widget itself.
+ // Retrieves the top level widget in a native view hierarchy
+ // starting at |native_view|. Top level widget is a widget with
+ // TYPE_WINDOW, TYPE_WINDOW_FRAMELESS, POPUP or MENU and has its own
+ // focus manager. This may be itself if the |native_view| is top level,
+ // or NULL if there is no toplevel in a native view hierarchy.
static Widget* GetTopLevelWidgetForNativeView(gfx::NativeView native_view);
// Returns all Widgets in |native_view|'s hierarchy, including itself if
@@ -252,8 +257,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
void NotifyNativeViewHierarchyChanged(bool attached,
gfx::NativeView native_view);
- // Returns the top level Widget in a hierarchy. Will return NULL the widget
- // is not yet attached to top leve widget's hierarchy.
+ // Returns the top level widget in a hierarchy (see is_top_level() for
+ // the definition of top level widget.) Will return NULL if called
+ // before the widget is attached to the top level widget's hierarchy.
Widget* GetTopLevelWidget();
const Widget* GetTopLevelWidget() const;
@@ -552,6 +558,12 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// if it exists and the root view otherwise.
virtual View* GetChildViewParent();
+ // True if the widget is considered top level widget. Top level widget
+ // is a widget of TYPE_WINDOW, TYPE_WINDOW_FRAMELESS, POPUP or MENU, and
+ // has a focus manager and input method object associated with it.
+ // TYPE_CONTROL and TYPE_TOOLTIP is not considered top level.
+ bool is_top_level() const { return is_top_level_; }
+
// Overridden from NativeWidgetDelegate:
virtual bool IsModal() const OVERRIDE;
virtual bool IsDialogBox() const OVERRIDE;
@@ -579,6 +591,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
virtual void OnMouseCaptureLost() OVERRIDE;
virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
virtual bool ExecuteCommand(int command_id) OVERRIDE;
+ virtual InputMethod* GetInputMethodDirect() OVERRIDE;
virtual Widget* AsWidget() OVERRIDE;
virtual const Widget* AsWidget() const OVERRIDE;
@@ -601,9 +614,6 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// TODO(beng): remove once we fold those objects onto this one.
void DestroyRootView();
- // Used for testing.
- void ReplaceFocusManager(FocusManager* focus_manager);
-
// TODO(beng): Remove NativeWidgetGtk's dependence on these:
// TODO(msw): Make this mouse state member private.
// If true, the mouse is currently down.
@@ -618,6 +628,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
gfx::Point last_mouse_event_position_;
private:
+ friend class NativeTextfieldViewsTest;
+ friend class NativeComboboxViewsTest;
friend class ScopedEvent;
// Returns whether capture should be released on mouse release.
@@ -634,6 +646,11 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// the delegate wants to use a specified bounds.
bool GetSavedBounds(gfx::Rect* bounds, bool* maximize);
+ // Sets a different InputMethod instance to this widget. The instance
+ // must not be initialized, the ownership will be assumed by the widget.
+ // It's only for testing purpose.
+ void ReplaceInputMethod(InputMethod* input_method);
+
internal::NativeWidgetPrivate* native_widget_;
ObserverList<Observer> observers_;
@@ -702,6 +719,11 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// initial focus for the widget.
bool focus_on_creation_;
+ scoped_ptr<InputMethod> input_method_;
+
+ // See |is_top_leve()| accessor.
+ bool is_top_level_;
+
// Factory used to create Compositors. Settable by tests.
static ui::Compositor*(*compositor_factory_)();