summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authoroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-14 08:01:05 +0000
committeroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-14 08:01:05 +0000
commitc55d4892c245bedab40fb51971658c824fcc1d6d (patch)
tree5dd2e37b0a2a3b539fd54dbc75156efd0955455d /views
parent95c26346db7dcfc103b5a3d36be7b3d1a771875f (diff)
downloadchromium_src-c55d4892c245bedab40fb51971658c824fcc1d6d.zip
chromium_src-c55d4892c245bedab40fb51971658c824fcc1d6d.tar.gz
chromium_src-c55d4892c245bedab40fb51971658c824fcc1d6d.tar.bz2
Move SetInitialFocus to Widget
Create InputMethod object per Top level NativeWidgetView - use MockInputMethod when IBUS is not available for now. Call OnNativeWidgetActivationChanged when activation changed. Handle InputFocus change when activation changed. This is temp solution until we have WM in place. BUG=none TEST=none Review URL: http://codereview.chromium.org/7353009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92495 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/desktop/desktop_window_view.cc23
-rw-r--r--views/desktop/desktop_window_view.h4
-rw-r--r--views/ime/mock_input_method.cc27
-rw-r--r--views/ime/mock_input_method.h1
-rw-r--r--views/views.gyp8
-rw-r--r--views/widget/native_widget_gtk.cc15
-rw-r--r--views/widget/native_widget_gtk.h13
-rw-r--r--views/widget/native_widget_views.cc50
-rw-r--r--views/widget/native_widget_views.h14
-rw-r--r--views/widget/native_widget_win.cc13
-rw-r--r--views/widget/native_widget_win.h16
-rw-r--r--views/widget/widget.cc12
-rw-r--r--views/widget/widget.h15
13 files changed, 138 insertions, 73 deletions
diff --git a/views/desktop/desktop_window_view.cc b/views/desktop/desktop_window_view.cc
index dc99de7..5fb92e9 100644
--- a/views/desktop/desktop_window_view.cc
+++ b/views/desktop/desktop_window_view.cc
@@ -38,6 +38,12 @@ class DesktopWindow : public Widget {
return new DesktopWindowRootView(desktop_window_view_, this);
}
+ virtual bool OnKeyEvent(const KeyEvent& event) OVERRIDE {
+ NativeWidgetViews* native_widget =
+ desktop_window_view_->active_native_widget();
+ return native_widget ? native_widget->OnKeyEvent(event) : false;
+ }
+
DesktopWindowView* desktop_window_view_;
DISALLOW_COPY_AND_ASSIGN(DesktopWindow);
@@ -89,7 +95,7 @@ class TestWindowContentView : public WidgetDelegateView {
DesktopWindowView* DesktopWindowView::desktop_window_view = NULL;
DesktopWindowView::DesktopWindowView(DesktopType type)
- : active_widget_(NULL),
+ : active_native_widget_(NULL),
type_(type) {
switch (type_) {
case DESKTOP_DEFAULT:
@@ -132,12 +138,13 @@ void DesktopWindowView::ActivateWidget(Widget* widget) {
if (widget && widget->IsActive())
return;
- if (active_widget_)
- active_widget_->OnActivate(false);
+ if (active_native_widget_)
+ active_native_widget_->OnActivate(false);
if (widget) {
widget->MoveToTop();
- active_widget_ = static_cast<NativeWidgetViews*>(widget->native_widget());
- active_widget_->OnActivate(true);
+ active_native_widget_ =
+ static_cast<NativeWidgetViews*>(widget->native_widget());
+ active_native_widget_->OnActivate(true);
if (!widget->HasObserver(this))
widget->AddObserver(this);
}
@@ -226,9 +233,9 @@ NonClientFrameView* DesktopWindowView::CreateNonClientFrameView() {
}
void DesktopWindowView::OnWidgetClosing(Widget* widget) {
- if (active_widget_ && static_cast<internal::NativeWidgetPrivate*>
- (active_widget_)->GetWidget() == widget)
- active_widget_ = NULL;
+ if (active_native_widget_ && static_cast<internal::NativeWidgetPrivate*>
+ (active_native_widget_)->GetWidget() == widget)
+ active_native_widget_ = NULL;
}
void DesktopWindowView::OnWidgetVisibilityChanged(Widget* widget,
diff --git a/views/desktop/desktop_window_view.h b/views/desktop/desktop_window_view.h
index 3962281..0d9a774 100644
--- a/views/desktop/desktop_window_view.h
+++ b/views/desktop/desktop_window_view.h
@@ -36,6 +36,8 @@ class DesktopWindowView : public WidgetDelegateView,
// is de-activated.
void ActivateWidget(Widget* widget);
+ NativeWidgetViews* active_native_widget() { return active_native_widget_; }
+
void CreateTestWindow(const std::wstring& title,
SkColor color,
gfx::Rect initial_bounds,
@@ -65,7 +67,7 @@ class DesktopWindowView : public WidgetDelegateView,
virtual void OnWidgetVisibilityChanged(Widget* widget, bool visible) OVERRIDE;
virtual void OnWidgetActivationChanged(Widget* widget, bool active) OVERRIDE;
- NativeWidgetViews* active_widget_;
+ NativeWidgetViews* active_native_widget_;
DesktopType type_;
Widget* widget_;
diff --git a/views/ime/mock_input_method.cc b/views/ime/mock_input_method.cc
index 88645523..0d06d19 100644
--- a/views/ime/mock_input_method.cc
+++ b/views/ime/mock_input_method.cc
@@ -23,6 +23,18 @@ MockInputMethod::MockInputMethod()
active_(true) {
}
+MockInputMethod::MockInputMethod(internal::InputMethodDelegate* delegate)
+ : composition_changed_(false),
+ focus_changed_(false),
+ text_input_type_changed_(false),
+ caret_bounds_changed_(false),
+ cancel_composition_called_(false),
+ locale_("en-US"),
+ direction_(base::i18n::LEFT_TO_RIGHT),
+ active_(true) {
+ set_delegate(delegate);
+}
+
MockInputMethod::~MockInputMethod() {
}
@@ -66,19 +78,20 @@ void MockInputMethod::DispatchKeyEvent(const KeyEvent& key) {
}
void MockInputMethod::OnTextInputTypeChanged(View* view) {
- DCHECK(IsViewFocused(view));
- text_input_type_changed_ = true;
+ if (IsViewFocused(view))
+ text_input_type_changed_ = true;
}
void MockInputMethod::OnCaretBoundsChanged(View* view) {
- DCHECK(IsViewFocused(view));
- caret_bounds_changed_ = true;
+ if (IsViewFocused(view))
+ caret_bounds_changed_ = true;
}
void MockInputMethod::CancelComposition(View* view) {
- DCHECK(IsViewFocused(view));
- cancel_composition_called_ = true;
- ClearResult();
+ if (IsViewFocused(view)) {
+ cancel_composition_called_ = true;
+ ClearResult();
+ }
}
std::string MockInputMethod::GetInputLocale() {
diff --git a/views/ime/mock_input_method.h b/views/ime/mock_input_method.h
index 3a1dffb..2691761 100644
--- a/views/ime/mock_input_method.h
+++ b/views/ime/mock_input_method.h
@@ -17,6 +17,7 @@ namespace views {
class MockInputMethod : public InputMethodBase {
public:
MockInputMethod();
+ explicit MockInputMethod(internal::InputMethodDelegate* delegate);
virtual ~MockInputMethod();
// Overridden from InputMethod:
diff --git a/views/views.gyp b/views/views.gyp
index 9284bea..5177013 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -277,6 +277,8 @@
'ime/input_method_ibus.h',
'ime/input_method_win.cc',
'ime/input_method_win.h',
+ 'ime/mock_input_method.cc',
+ 'ime/mock_input_method.h',
'ime/text_input_client.h',
'ime/text_input_type_tracker.h',
'ime/text_input_type_tracker.cc',
@@ -429,6 +431,10 @@
'dependencies': [
'../build/linux/system.gyp:ibus',
],
+ 'sources/': [
+ ['exclude', 'ime/mock_input_method.cc'],
+ ['exclude', 'ime/mock_input_method.h'],
+ ],
}, { # else: use_ibus != 1
'sources/': [
['exclude', 'ime/character_composer.cc'],
@@ -476,8 +482,6 @@
'events/event_unittest.cc',
'focus/accelerator_handler_gtk_unittest.cc',
'focus/focus_manager_unittest.cc',
- 'ime/mock_input_method.cc',
- 'ime/mock_input_method.h',
'ime/character_composer_unittest.cc',
'layout/grid_layout_unittest.cc',
'layout/box_layout_unittest.cc',
diff --git a/views/widget/native_widget_gtk.cc b/views/widget/native_widget_gtk.cc
index 14a4f31..7fbe649 100644
--- a/views/widget/native_widget_gtk.cc
+++ b/views/widget/native_widget_gtk.cc
@@ -372,7 +372,6 @@ NativeWidgetGtk::NativeWidgetGtk(internal::NativeWidgetDelegate* delegate)
transient_to_parent_(false),
got_initial_focus_in_(false),
has_focus_(false),
- focus_on_creation_(true),
always_on_top_(false),
is_double_buffered_(false),
should_handle_menu_key_release_(false),
@@ -524,15 +523,6 @@ void NativeWidgetGtk::IsActiveChanged() {
delegate_->OnNativeWidgetActivationChanged(IsActive());
}
-void NativeWidgetGtk::SetInitialFocus() {
- if (!focus_on_creation_)
- return;
-
- View* v = GetWidget()->widget_delegate()->GetInitiallyFocusedView();
- if (v)
- v->RequestFocus();
-}
-
void NativeWidgetGtk::ResetDropTarget() {
ignore_drag_leave_ = false;
drop_target_.reset(NULL);
@@ -1658,7 +1648,10 @@ gboolean NativeWidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) {
// See description of got_initial_focus_in_ for details on this.
if (!got_initial_focus_in_) {
got_initial_focus_in_ = true;
- SetInitialFocus();
+ // Sets initial focus here. On X11/Gtk, window creation
+ // is asynchronous and a focus request has to be made after a window
+ // gets created.
+ GetWidget()->SetInitialFocus();
}
return false;
}
diff --git a/views/widget/native_widget_gtk.h b/views/widget/native_widget_gtk.h
index 425d42a..82f8f13 100644
--- a/views/widget/native_widget_gtk.h
+++ b/views/widget/native_widget_gtk.h
@@ -94,11 +94,6 @@ class NativeWidgetGtk : public internal::NativeWidgetPrivate,
// Invoked when the active status changes.
virtual void IsActiveChanged();
- // Sets initial focus on a new window. On X11/Gtk, window creation
- // is asynchronous and a focus request has to be made after a window
- // gets created. This will not be called on a TYPE_CHILD widget.
- virtual void SetInitialFocus();
-
// Sets the drop target to NULL. This is invoked by DropTargetGTK when the
// drop is done.
void ResetDropTarget();
@@ -147,10 +142,6 @@ class NativeWidgetGtk : public internal::NativeWidgetPrivate,
// detached widget.
static void RegisterChildExposeHandler(GtkWidget* widget);
- void set_focus_on_creation(bool focus_on_creation) {
- focus_on_creation_ = focus_on_creation;
- }
-
// Overridden from internal::NativeWidgetPrivate:
virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE;
virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE;
@@ -426,10 +417,6 @@ class NativeWidgetGtk : public internal::NativeWidgetPrivate,
// this to determine whether we should process the event.
bool has_focus_;
- // Whether we should SetFocus() on a newly created window after
- // Init(). Defaults to true.
- bool focus_on_creation_;
-
// If true, the window stays on top of the screen. This is only used
// for types other than TYPE_CHILD.
bool always_on_top_;
diff --git a/views/widget/native_widget_views.cc b/views/widget/native_widget_views.cc
index bbfa8c5..47bb1a7 100644
--- a/views/widget/native_widget_views.cc
+++ b/views/widget/native_widget_views.cc
@@ -11,6 +11,12 @@
#include "views/widget/native_widget_view.h"
#include "views/widget/root_view.h"
+#if defined(HAVE_IBUS)
+#include "views/ime/input_methodc_ibus.h"
+#else
+#include "views/ime/mock_input_method.h"
+#endif
+
namespace views {
////////////////////////////////////////////////////////////////////////////////
@@ -43,10 +49,35 @@ const View* NativeWidgetViews::GetView() const {
}
void NativeWidgetViews::OnActivate(bool active) {
+ 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();
+ }
view_->SchedulePaint();
}
+bool NativeWidgetViews::OnKeyEvent(const KeyEvent& key_event) {
+ GetInputMethodNative()->DispatchKeyEvent(key_event);
+ return true;
+}
+
+void NativeWidgetViews::DispatchKeyEventPostIME(const KeyEvent& key) {
+ // TODO(oshima): GTK impl handles menu_key in special way. This may be
+ // necessary when running under NativeWidgetX.
+ delegate_->OnKeyEvent(key);
+}
+
////////////////////////////////////////////////////////////////////////////////
// NativeWidgetViews, NativeWidget implementation:
@@ -191,11 +222,23 @@ bool NativeWidgetViews::HasKeyboardCapture() {
}
InputMethod* NativeWidgetViews::GetInputMethodNative() {
- return GetParentNativeWidget()->GetInputMethodNative();
+ if (!input_method_.get()) {
+#if defined(HAVE_IBUS)
+ input_method_.reset(static_cast<InputMethod*>(new InputMethodIBus(this)));
+#else
+ // TODO(suzhe|oshima): Figure out what to do on windows.
+ input_method_.reset(new MockInputMethod(this));
+#endif
+ input_method_->Init(GetWidget());
+ }
+ return input_method_.get();
}
void NativeWidgetViews::ReplaceInputMethod(InputMethod* input_method) {
- GetParentNativeWidget()->ReplaceInputMethod(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) {
@@ -283,6 +326,8 @@ void NativeWidgetViews::Close() {
}
void NativeWidgetViews::CloseNow() {
+ // reset input_method before destroying widget.
+ input_method_.reset();
// TODO(beng): what about the other case??
if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
delete this;
@@ -293,6 +338,7 @@ void NativeWidgetViews::EnableClose(bool enable) {
void NativeWidgetViews::Show() {
view_->SetVisible(true);
+ GetWidget()->SetInitialFocus();
}
void NativeWidgetViews::Hide() {
diff --git a/views/widget/native_widget_views.h b/views/widget/native_widget_views.h
index c90f166..30567db 100644
--- a/views/widget/native_widget_views.h
+++ b/views/widget/native_widget_views.h
@@ -8,6 +8,7 @@
#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 {
@@ -20,7 +21,8 @@ class NativeWidgetView;
//
// A NativeWidget implementation that uses another View as its native widget.
//
-class NativeWidgetViews : public internal::NativeWidgetPrivate {
+class NativeWidgetViews : public internal::NativeWidgetPrivate,
+ public internal::InputMethodDelegate {
public:
explicit NativeWidgetViews(internal::NativeWidgetDelegate* delegate);
virtual ~NativeWidgetViews();
@@ -29,7 +31,9 @@ class NativeWidgetViews : public internal::NativeWidgetPrivate {
View* GetView();
const View* GetView() const;
+ // TODO(oshima): These will be moved to WM API.
void OnActivate(bool active);
+ bool OnKeyEvent(const KeyEvent& key_event);
void set_delete_native_view(bool delete_native_view) {
delete_native_view_ = delete_native_view;
@@ -118,14 +122,14 @@ class NativeWidgetViews : public internal::NativeWidgetPrivate {
virtual void SetCursor(gfx::NativeCursor cursor) OVERRIDE;
virtual void ClearNativeFocus() OVERRIDE;
+ // Overridden from internal::InputMethodDelegate
+ virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE;
+
private:
// These functions may return NULL during Widget destruction.
internal::NativeWidgetPrivate* GetParentNativeWidget();
const internal::NativeWidgetPrivate* GetParentNativeWidget() const;
- // Called by the NativeWidgetView when it is deleted.
- void OnDestroy();
-
internal::NativeWidgetDelegate* delegate_;
scoped_ptr<internal::NativeWidgetView> view_;
@@ -148,6 +152,8 @@ class NativeWidgetViews : public internal::NativeWidgetPrivate {
bool delete_native_view_;
+ scoped_ptr<InputMethod> input_method_;
+
DISALLOW_COPY_AND_ASSIGN(NativeWidgetViews);
};
diff --git a/views/widget/native_widget_win.cc b/views/widget/native_widget_win.cc
index 98c080c..17b28e9 100644
--- a/views/widget/native_widget_win.cc
+++ b/views/widget/native_widget_win.cc
@@ -369,7 +369,6 @@ NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate)
ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)),
ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
can_update_layered_window_(true),
- focus_on_creation_(true),
restore_focus_when_enabled_(false),
accessibility_view_events_index_(-1),
accessibility_view_events_(kMaxAccessibilityViewEvents),
@@ -2141,15 +2140,9 @@ void NativeWidgetWin::OnScreenReaderDetected() {
}
void NativeWidgetWin::SetInitialFocus() {
- if (!focus_on_creation_)
- return;
-
- // TODO(beng): move to Widget.
- View* v = GetWidget()->widget_delegate()->GetInitiallyFocusedView();
- if (v) {
- v->RequestFocus();
- } else if (!(GetWindowLong(GWL_EXSTYLE) & WS_EX_TRANSPARENT) &&
- !(GetWindowLong(GWL_EXSTYLE) & WS_EX_NOACTIVATE)) {
+ if (!GetWidget()->SetInitialFocus() &&
+ !(GetWindowLong(GWL_EXSTYLE) & WS_EX_TRANSPARENT) &&
+ !(GetWindowLong(GWL_EXSTYLE) & WS_EX_NOACTIVATE)) {
// The window does not get keyboard messages unless we focus it.
SetFocus(GetNativeView());
}
diff --git a/views/widget/native_widget_win.h b/views/widget/native_widget_win.h
index ac7924d..a6dd942 100644
--- a/views/widget/native_widget_win.h
+++ b/views/widget/native_widget_win.h
@@ -463,19 +463,9 @@ class NativeWidgetWin : public ui::WindowImpl,
// Called when a MSAA screen reader client is detected.
virtual void OnScreenReaderDetected();
- // Sets-up the focus manager with the view that should have focus when the
- // window is shown the first time. If NULL is returned, the focus goes to the
- // button if there is one, otherwise the to the Cancel button.
- virtual void SetInitialFocus();
-
// Executes the specified SC_command.
void ExecuteSystemMenuCommand(int command);
- // Accessors and setters for various properties.
- void set_focus_on_creation(bool focus_on_creation) {
- focus_on_creation_ = focus_on_creation;
- }
-
// The TooltipManager. This is NULL if there is a problem creating the
// underlying tooltip window.
// WARNING: RootView's destructor calls into the TooltipManager. As such, this
@@ -532,6 +522,8 @@ class NativeWidgetWin : public ui::WindowImpl,
void RestoreEnabledIfNecessary();
+ void SetInitialFocus();
+
// Overridden from internal::InputMethodDelegate
virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE;
@@ -586,10 +578,6 @@ class NativeWidgetWin : public ui::WindowImpl,
// store if necessary.
bool can_update_layered_window_;
- // Whether we should SetFocus() on a newly created window after
- // Init(). Defaults to true.
- bool focus_on_creation_;
-
// Whether the focus should be restored next time we get enabled. Needed to
// restore focus correctly when Windows modal dialogs are displayed.
bool restore_focus_when_enabled_;
diff --git a/views/widget/widget.cc b/views/widget/widget.cc
index 047cf05..69386a6 100644
--- a/views/widget/widget.cc
+++ b/views/widget/widget.cc
@@ -142,7 +142,8 @@ Widget::Widget()
disable_inactive_rendering_(false),
widget_closed_(false),
saved_maximized_state_(false),
- minimum_size_(100, 100) {
+ minimum_size_(100, 100),
+ focus_on_creation_(true) {
}
Widget::~Widget() {
@@ -711,6 +712,15 @@ void Widget::TooltipTextChanged(View* view) {
manager->TooltipTextChanged(view);
}
+bool Widget::SetInitialFocus() {
+ if (!focus_on_creation_)
+ return true;
+ View* v = widget_delegate_->GetInitiallyFocusedView();
+ if (v)
+ v->RequestFocus();
+ return !!v;
+}
+
View* Widget::GetChildViewParent() {
return GetContentsView() ? GetContentsView() : GetRootView();
}
diff --git a/views/widget/widget.h b/views/widget/widget.h
index 99e706f..af9a899 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -521,6 +521,16 @@ class Widget : public internal::NativeWidgetDelegate,
// Invoked when the tooltip text changes for the specified views.
void TooltipTextChanged(View* view);
+ // Sets-up the focus manager with the view that should have focus when the
+ // window is shown the first time. Returns true if the initial focus has been
+ // set or the widget should not set the initial focus, or false if the caller
+ // should set the initial focus (if any).
+ bool SetInitialFocus();
+
+ void set_focus_on_creation(bool focus_on_creation) {
+ focus_on_creation_ = focus_on_creation;
+ }
+
// Returns a View* that any child Widgets backed by NativeWidgetViews
// are added to. The default implementation returns the contents view
// if it exists and the root view otherwise.
@@ -663,6 +673,11 @@ class Widget : public internal::NativeWidgetDelegate,
// The smallest size the window can be.
gfx::Size minimum_size_;
+ // Focus is automatically set to the view provided by the delegate
+ // when the widget is shown. Set this value to false to override
+ // initial focus for the widget.
+ bool focus_on_creation_;
+
// Factory used to create Compositors. Settable by tests.
static ui::Compositor*(*compositor_factory_)();