summaryrefslogtreecommitdiffstats
path: root/chromium/ui/views/focus
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/views/focus')
-rw-r--r--chromium/ui/views/focus/accelerator_handler.h46
-rw-r--r--chromium/ui/views/focus/accelerator_handler_aura.cc26
-rw-r--r--chromium/ui/views/focus/accelerator_handler_win.cc55
-rw-r--r--chromium/ui/views/focus/focus_manager.cc70
-rw-r--r--chromium/ui/views/focus/focus_manager.h11
-rw-r--r--chromium/ui/views/focus/focus_manager_test.cc18
-rw-r--r--chromium/ui/views/focus/focus_manager_test.h9
-rw-r--r--chromium/ui/views/focus/focus_manager_unittest.cc131
-rw-r--r--chromium/ui/views/focus/focus_manager_unittest_win.cc281
-rw-r--r--chromium/ui/views/focus/focus_traversal_unittest.cc38
-rw-r--r--chromium/ui/views/focus/view_storage.h2
11 files changed, 152 insertions, 535 deletions
diff --git a/chromium/ui/views/focus/accelerator_handler.h b/chromium/ui/views/focus/accelerator_handler.h
deleted file mode 100644
index 29f353e697c..00000000000
--- a/chromium/ui/views/focus/accelerator_handler.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
-#define UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
-
-#include "build/build_config.h"
-
-#include <set>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/message_loop/message_loop.h"
-#include "ui/views/views_export.h"
-
-namespace views {
-
-#if defined(USE_AURA) && defined(USE_X11)
-// Dispatch an XEvent to the RootView. Return true if the event was dispatched
-// and handled, false otherwise.
-bool VIEWS_EXPORT DispatchXEvent(XEvent* xevent);
-#endif // USE_AURA && USE_X11
-
-// This class delegates the key messages to the associated FocusManager class
-// for the window that is receiving these messages for accelerator processing.
-class VIEWS_EXPORT AcceleratorHandler : public base::MessageLoop::Dispatcher {
- public:
- AcceleratorHandler();
-
- // Dispatcher method. This returns true if an accelerator was processed by the
- // focus manager
- virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE;
-
- private:
-#if defined(OS_WIN)
- // The keys currently pressed and consumed by the FocusManager.
- std::set<WPARAM> pressed_keys_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(AcceleratorHandler);
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
diff --git a/chromium/ui/views/focus/accelerator_handler_aura.cc b/chromium/ui/views/focus/accelerator_handler_aura.cc
deleted file mode 100644
index 8daa0f394e9..00000000000
--- a/chromium/ui/views/focus/accelerator_handler_aura.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/focus/accelerator_handler.h"
-
-namespace views {
-
-AcceleratorHandler::AcceleratorHandler() {
-}
-
-bool AcceleratorHandler::Dispatch(const base::NativeEvent& event) {
-#if defined(OS_WIN)
- TranslateMessage(&event);
- DispatchMessage(&event);
-#endif // defined(OS_WIN)
- return true;
-}
-
-#if defined(USE_X11)
-bool DispatchXEvent(XEvent* xev) {
- return false;
-}
-#endif // defined(USE_X11)
-
-} // namespace views
diff --git a/chromium/ui/views/focus/accelerator_handler_win.cc b/chromium/ui/views/focus/accelerator_handler_win.cc
deleted file mode 100644
index ea82daed717..00000000000
--- a/chromium/ui/views/focus/accelerator_handler_win.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/focus/accelerator_handler.h"
-
-#include "ui/events/event.h"
-#include "ui/events/keycodes/keyboard_code_conversion_win.h"
-#include "ui/events/keycodes/keyboard_codes.h"
-#include "ui/views/focus/focus_manager.h"
-#include "ui/views/widget/widget.h"
-
-namespace views {
-
-AcceleratorHandler::AcceleratorHandler() {
-}
-
-bool AcceleratorHandler::Dispatch(const base::NativeEvent& msg) {
- if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) {
- Widget* widget = Widget::GetTopLevelWidgetForNativeView(msg.hwnd);
- FocusManager* focus_manager = widget ? widget->GetFocusManager() : NULL;
- if (focus_manager) {
- switch (msg.message) {
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN: {
- ui::KeyEvent event(msg, false);
- if (!focus_manager->OnKeyEvent(event)) {
- // Record that this key is pressed so we can remember not to
- // translate and dispatch the associated WM_KEYUP.
- pressed_keys_.insert(msg.wParam);
- return true;
- }
- break;
- }
- case WM_KEYUP:
- case WM_SYSKEYUP: {
- std::set<WPARAM>::iterator iter = pressed_keys_.find(msg.wParam);
- if (iter != pressed_keys_.end()) {
- // Don't translate/dispatch the KEYUP since we have eaten the
- // associated KEYDOWN.
- pressed_keys_.erase(iter);
- return true;
- }
- break;
- }
- }
- }
- }
-
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- return true;
-}
-
-} // namespace views
diff --git a/chromium/ui/views/focus/focus_manager.cc b/chromium/ui/views/focus/focus_manager.cc
index f52712e6234..4808b4422cb 100644
--- a/chromium/ui/views/focus/focus_manager.cc
+++ b/chromium/ui/views/focus/focus_manager.cc
@@ -11,6 +11,10 @@
#include "base/logging.h"
#include "build/build_config.h"
#include "ui/base/accelerators/accelerator.h"
+#include "ui/base/ime/input_method.h"
+#include "ui/base/ime/text_input_client.h"
+#include "ui/base/ime/text_input_focus_manager.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/views/focus/focus_manager_delegate.h"
@@ -64,6 +68,7 @@ bool FocusManager::OnKeyEvent(const ui::KeyEvent& event) {
modifiers |= ui::EF_ALT_DOWN;
ui::Accelerator accelerator(event.key_code(), modifiers);
accelerator.set_type(event.type());
+ accelerator.set_is_repeat(event.IsRepeat());
if (event.type() == ui::ET_KEY_PRESSED) {
// If the focused view wants to process the key event as is, let it be.
@@ -75,20 +80,10 @@ bool FocusManager::OnKeyEvent(const ui::KeyEvent& event) {
// Note that we don't do focus traversal if the root window is not part of
// the active window hierarchy as this would mean we have no focused view
// and would focus the first focusable view.
-#if defined(OS_WIN) && !defined(USE_AURA)
- HWND top_window = widget_->GetNativeView();
- HWND active_window = ::GetActiveWindow();
- if ((active_window == top_window || ::IsChild(active_window, top_window)) &&
- IsTabTraversalKeyEvent(event)) {
- AdvanceFocus(event.IsShiftDown());
- return false;
- }
-#else
if (IsTabTraversalKeyEvent(event)) {
AdvanceFocus(event.IsShiftDown());
return false;
}
-#endif
if (arrow_key_traversal_enabled_ && ProcessArrowKeyTraversal(event))
return false;
@@ -319,8 +314,13 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view,
void FocusManager::SetFocusedViewWithReason(
View* view, FocusChangeReason reason) {
- if (focused_view_ == view)
+ if (focused_view_ == view) {
+ // In the case that the widget lost the focus and gained it back without
+ // changing the focused view, we have to make the text input client focused.
+ // TODO(yukishiino): Remove this hack once we fix http://crbug.com/383236
+ FocusTextInputClient(focused_view_);
return;
+ }
base::AutoReset<bool> auto_changing_focus(&is_changing_focus_, true);
// Update the reason for the focus change (since this is checked by
@@ -331,14 +331,18 @@ void FocusManager::SetFocusedViewWithReason(
View* old_focused_view = focused_view_;
focused_view_ = view;
- if (old_focused_view)
+ if (old_focused_view) {
old_focused_view->Blur();
+ BlurTextInputClient(old_focused_view);
+ }
// Also make |focused_view_| the stored focus view. This way the stored focus
// view is remembered if focus changes are requested prior to a show or while
// hidden.
SetStoredFocusView(focused_view_);
- if (focused_view_)
+ if (focused_view_) {
+ FocusTextInputClient(focused_view_);
focused_view_->Focus();
+ }
FOR_EACH_OBSERVER(FocusChangeListener, focus_change_listeners_,
OnDidChangeFocus(old_focused_view, focused_view_));
@@ -437,6 +441,46 @@ void FocusManager::ClearStoredFocusedView() {
SetStoredFocusView(NULL);
}
+void FocusManager::OnTextInputClientChanged(View* view) {
+ if (view == focused_view_)
+ FocusTextInputClient(view);
+}
+
+void FocusManager::FocusTextInputClient(View* view) {
+ if (!switches::IsTextInputFocusManagerEnabled())
+ return;
+
+ // If the widget is not active, do not steal the text input focus.
+ if (!widget_->IsActive())
+ return;
+
+ ui::TextInputClient* text_input_client =
+ view ? view->GetTextInputClient() : NULL;
+ ui::TextInputFocusManager::GetInstance()->
+ FocusTextInputClient(text_input_client);
+ ui::InputMethod* input_method = widget_->GetHostInputMethod();
+ if (input_method) {
+ input_method->OnTextInputTypeChanged(text_input_client);
+ input_method->OnCaretBoundsChanged(text_input_client);
+ }
+}
+
+void FocusManager::BlurTextInputClient(View* view) {
+ if (!switches::IsTextInputFocusManagerEnabled())
+ return;
+
+ ui::TextInputClient* text_input_client =
+ view ? view->GetTextInputClient() : NULL;
+ if (text_input_client && text_input_client->HasCompositionText()) {
+ text_input_client->ConfirmCompositionText();
+ ui::InputMethod* input_method = widget_->GetHostInputMethod();
+ if (input_method && input_method->GetTextInputClient() == text_input_client)
+ input_method->CancelComposition(text_input_client);
+ }
+ ui::TextInputFocusManager::GetInstance()->
+ BlurTextInputClient(text_input_client);
+}
+
// Find the next (previous if reverse is true) focusable view for the specified
// FocusTraversable, starting at the specified view, traversing down the
// FocusTraversable hierarchy.
diff --git a/chromium/ui/views/focus/focus_manager.h b/chromium/ui/views/focus/focus_manager.h
index 7d7c7dc16e0..ebdc2a3d88e 100644
--- a/chromium/ui/views/focus/focus_manager.h
+++ b/chromium/ui/views/focus/focus_manager.h
@@ -72,8 +72,8 @@
// is FocusTraversable.
namespace ui {
-class AcceleratorTarget;
class AcceleratorManager;
+class AcceleratorTarget;
class EventHandler;
class KeyEvent;
}
@@ -213,6 +213,15 @@ class VIEWS_EXPORT FocusManager {
// Returns true if in the process of changing the focused view.
bool is_changing_focus() const { return is_changing_focus_; }
+ // Changes the text input focus to |view->GetTextInputClient()| iff |view|
+ // is focused. Views must call this method when their internal
+ // TextInputClient instance changes.
+ void OnTextInputClientChanged(View* view);
+
+ // Moves the text input focus into/out from |view|.
+ void FocusTextInputClient(View* view);
+ void BlurTextInputClient(View* view);
+
// Disable shortcut handling.
static void set_shortcut_handling_suspended(bool suspended) {
shortcut_handling_suspended_ = suspended;
diff --git a/chromium/ui/views/focus/focus_manager_test.cc b/chromium/ui/views/focus/focus_manager_test.cc
index 528f345ce63..6debc794dff 100644
--- a/chromium/ui/views/focus/focus_manager_test.cc
+++ b/chromium/ui/views/focus/focus_manager_test.cc
@@ -100,24 +100,6 @@ void FocusManagerTest::SetAccessiblePanes(const std::vector<View*>& panes) {
accessible_panes_ = panes;
}
-#if defined(OS_WIN) && !defined(USE_AURA)
-void FocusManagerTest::SimulateActivateWindow() {
- SendMessage(GetWidget()->GetNativeWindow(), WM_ACTIVATE, WA_ACTIVE, NULL);
-}
-
-void FocusManagerTest::SimulateDeactivateWindow() {
- SendMessage(GetWidget()->GetNativeWindow(), WM_ACTIVATE, WA_INACTIVE, NULL);
-}
-
-void FocusManagerTest::PostKeyDown(ui::KeyboardCode key_code) {
- PostMessage(GetWidget()->GetNativeView(), WM_KEYDOWN, key_code, 0);
-}
-
-void FocusManagerTest::PostKeyUp(ui::KeyboardCode key_code) {
- PostMessage(GetWidget()->GetNativeView(), WM_KEYUP, key_code, 0);
-}
-#endif
-
////////////////////////////////////////////////////////////////////////////////
// TestFocusChangeListener
diff --git a/chromium/ui/views/focus/focus_manager_test.h b/chromium/ui/views/focus/focus_manager_test.h
index 4afbf4f7758..e54138673b0 100644
--- a/chromium/ui/views/focus/focus_manager_test.h
+++ b/chromium/ui/views/focus/focus_manager_test.h
@@ -43,15 +43,6 @@ class FocusManagerTest : public ViewsTestBase, public WidgetDelegate {
// For testing FocusManager::RotatePaneFocus().
void SetAccessiblePanes(const std::vector<View*>& panes);
-#if defined(OS_WIN) && !defined(USE_AURA)
- // Mocks activating/deactivating the window.
- void SimulateActivateWindow();
- void SimulateDeactivateWindow();
-
- void PostKeyDown(ui::KeyboardCode key_code);
- void PostKeyUp(ui::KeyboardCode key_code);
-#endif
-
private:
View* contents_view_;
FocusChangeListener* focus_change_listener_;
diff --git a/chromium/ui/views/focus/focus_manager_unittest.cc b/chromium/ui/views/focus/focus_manager_unittest.cc
index fcb82b7f310..3513e2b70a7 100644
--- a/chromium/ui/views/focus/focus_manager_unittest.cc
+++ b/chromium/ui/views/focus/focus_manager_unittest.cc
@@ -2,38 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ui/views/focus/focus_manager.h"
+
#include <utility>
#include <vector>
+#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
+#include "ui/aura/client/focus_client.h"
+#include "ui/aura/window.h"
#include "ui/base/accelerators/accelerator.h"
+#include "ui/base/ime/dummy_text_input_client.h"
+#include "ui/base/ime/text_input_focus_manager.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/views/accessible_pane_view.h"
#include "ui/views/controls/button/label_button.h"
-#include "ui/views/controls/textfield/textfield.h"
-#include "ui/views/focus/accelerator_handler.h"
#include "ui/views/focus/focus_manager_factory.h"
#include "ui/views/focus/focus_manager_test.h"
#include "ui/views/focus/widget_focus_manager.h"
#include "ui/views/widget/widget.h"
-#if defined(USE_AURA)
-#include "ui/aura/client/focus_client.h"
-#include "ui/aura/window.h"
-#endif
-
namespace views {
-void FocusNativeView(gfx::NativeView view) {
-#if defined(USE_AURA)
- aura::client::GetFocusClient(view)->FocusWindow(view);
-#elif defined(OS_WIN)
- SetFocus(view);
-#else
-#error
-#endif
-}
-
enum FocusTestEventType {
ON_FOCUS = 0,
ON_BLUR
@@ -67,6 +58,8 @@ class SimpleTestView : public View {
private:
std::vector<FocusTestEvent>* event_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(SimpleTestView);
};
// Tests that the appropriate Focus related methods are called when a View
@@ -149,14 +142,14 @@ TEST_F(FocusManagerTest, WidgetFocusChangeListener) {
widget_listener.ClearFocusChanges();
gfx::NativeView native_view1 = widget1->GetNativeView();
- FocusNativeView(native_view1);
+ aura::client::GetFocusClient(native_view1)->FocusWindow(native_view1);
ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size()));
EXPECT_EQ(native_view1, widget_listener.focus_changes()[0].second);
EXPECT_EQ(native_view1, widget_listener.focus_changes()[1].second);
widget_listener.ClearFocusChanges();
gfx::NativeView native_view2 = widget2->GetNativeView();
- FocusNativeView(native_view2);
+ aura::client::GetFocusClient(native_view2)->FocusWindow(native_view2);
ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size()));
EXPECT_EQ(NativeViewPair(native_view1, native_view2),
widget_listener.focus_changes()[0]);
@@ -164,26 +157,6 @@ TEST_F(FocusManagerTest, WidgetFocusChangeListener) {
widget_listener.focus_changes()[1]);
}
-#if !defined(USE_AURA)
-class TestTextfield : public Textfield {
- public:
- TestTextfield() {}
- virtual gfx::NativeView TestGetNativeControlView() {
- return native_wrapper_->GetTestingHandle();
- }
-};
-
-// Tests that NativeControls do set the focused View appropriately on the
-// FocusManager.
-TEST_F(FocusManagerTest, DISABLED_FocusNativeControls) {
- TestTextfield* textfield = new TestTextfield();
- GetContentsView()->AddChildView(textfield);
- // Simulate the native view getting the native focus (such as by user click).
- FocusNativeView(textfield->TestGetNativeControlView());
- EXPECT_EQ(textfield, GetFocusManager()->GetFocusedView());
-}
-#endif
-
// Counts accelerator calls.
class TestAcceleratorTarget : public ui::AcceleratorTarget {
public:
@@ -537,10 +510,11 @@ class FocusManagerDtorTest : public FocusManagerTest {
class LabelButtonDtorTracked : public LabelButton {
public:
- LabelButtonDtorTracked(const string16& text, DtorTrackVector* dtor_tracker)
+ LabelButtonDtorTracked(const base::string16& text,
+ DtorTrackVector* dtor_tracker)
: LabelButton(NULL, text),
dtor_tracker_(dtor_tracker) {
- SetStyle(STYLE_NATIVE_TEXTBUTTON);
+ SetStyle(STYLE_BUTTON);
};
virtual ~LabelButtonDtorTracked() {
dtor_tracker_->push_back("LabelButtonDtorTracked");
@@ -586,25 +560,6 @@ class FocusManagerDtorTest : public FocusManagerTest {
DtorTrackVector dtor_tracker_;
};
-#if !defined(USE_AURA)
-TEST_F(FocusManagerDtorTest, FocusManagerDestructedLast) {
- // Setup views hierarchy.
- GetContentsView()->AddChildView(new TestTextfield());
- GetContentsView()->AddChildView(new LabelButtonDtorTracked(
- ASCIIToUTF16("button"), &dtor_tracker_));
-
- // Close the window.
- GetWidget()->Close();
- RunPendingMessages();
-
- // Test window, button and focus manager should all be destructed.
- ASSERT_EQ(3, static_cast<int>(dtor_tracker_.size()));
-
- // Focus manager should be the last one to destruct.
- ASSERT_STREQ("FocusManagerDtorTracked", dtor_tracker_[2].c_str());
-}
-#endif
-
namespace {
class FocusInAboutToRequestFocusFromTabTraversalView : public View {
@@ -819,16 +774,72 @@ TEST_F(FocusManagerTest, StoreFocusedView) {
View view;
GetFocusManager()->SetFocusedView(&view);
GetFocusManager()->StoreFocusedView(false);
+ EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
// Repeat with |true|.
GetFocusManager()->SetFocusedView(&view);
GetFocusManager()->StoreFocusedView(true);
+ EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
}
+class TextInputTestView : public View {
+ public:
+ TextInputTestView() {}
+
+ virtual ui::TextInputClient* GetTextInputClient() OVERRIDE {
+ return &text_input_client_;
+ }
+
+ private:
+ ui::DummyTextInputClient text_input_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(TextInputTestView);
+};
+
+TEST_F(FocusManagerTest, TextInputClient) {
+ base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
+ cmd_line->AppendSwitch(switches::kEnableTextInputFocusManager);
+
+ View* view = new TextInputTestView;
+ ui::TextInputClient* text_input_client = view->GetTextInputClient();
+ view->SetFocusable(true);
+ GetContentsView()->AddChildView(view);
+ ui::TextInputFocusManager* text_input_focus_manager =
+ ui::TextInputFocusManager::GetInstance();
+
+ GetFocusManager()->SetFocusedView(view);
+ EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
+ EXPECT_EQ(text_input_client,
+ text_input_focus_manager->GetFocusedTextInputClient());
+ GetFocusManager()->StoreFocusedView(false);
+ EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
+ EXPECT_EQ(text_input_client,
+ text_input_focus_manager->GetFocusedTextInputClient());
+
+ // Repeat with |true|.
+ GetFocusManager()->SetFocusedView(view);
+ EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
+ EXPECT_EQ(text_input_client,
+ text_input_focus_manager->GetFocusedTextInputClient());
+ GetFocusManager()->StoreFocusedView(true);
+ EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
+ EXPECT_EQ(text_input_client,
+ text_input_focus_manager->GetFocusedTextInputClient());
+
+ // Focus the view twice in a row.
+ GetFocusManager()->SetFocusedView(view);
+ EXPECT_EQ(text_input_client,
+ text_input_focus_manager->GetFocusedTextInputClient());
+ ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(NULL);
+ GetFocusManager()->SetFocusedView(view);
+ EXPECT_EQ(text_input_client,
+ text_input_focus_manager->GetFocusedTextInputClient());
+}
+
namespace {
// Trivial WidgetDelegate implementation that allows setting return value of
diff --git a/chromium/ui/views/focus/focus_manager_unittest_win.cc b/chromium/ui/views/focus/focus_manager_unittest_win.cc
deleted file mode 100644
index 267a8b78df3..00000000000
--- a/chromium/ui/views/focus/focus_manager_unittest_win.cc
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/focus/focus_manager.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "base/run_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/events/event.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/focus/accelerator_handler.h"
-#include "ui/views/focus/focus_manager_test.h"
-#include "ui/views/widget/widget.h"
-
-namespace views {
-
-namespace {
-
-class MessageTrackingView : public View {
- public:
- MessageTrackingView() : accelerator_pressed_(false) {
- }
-
- void Reset() {
- accelerator_pressed_ = false;
- keys_pressed_.clear();
- keys_released_.clear();
- }
-
- const std::vector<ui::KeyboardCode>& keys_pressed() const {
- return keys_pressed_;
- }
-
- const std::vector<ui::KeyboardCode>& keys_released() const {
- return keys_released_;
- }
-
- bool accelerator_pressed() const {
- return accelerator_pressed_;
- }
-
- // Overridden from View:
- virtual bool OnKeyPressed(const ui::KeyEvent& e) OVERRIDE {
- keys_pressed_.push_back(e.key_code());
- return true;
- }
- virtual bool OnKeyReleased(const ui::KeyEvent& e) OVERRIDE {
- keys_released_.push_back(e.key_code());
- return true;
- }
- virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
- accelerator_pressed_ = true;
- return true;
- }
-
- private:
- bool accelerator_pressed_;
- std::vector<ui::KeyboardCode> keys_pressed_;
- std::vector<ui::KeyboardCode> keys_released_;
-
- DISALLOW_COPY_AND_ASSIGN(MessageTrackingView);
-};
-
-} // namespace
-
-// Test that when activating/deactivating the top window, the focus is stored/
-// restored properly.
-TEST_F(FocusManagerTest, FocusStoreRestore) {
- // Simulate an activate, otherwise the deactivate isn't going to do anything.
- SimulateActivateWindow();
-
- LabelButton* button = new LabelButton(NULL, ASCIIToUTF16("Press me"));
- button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON);
- View* view = new View();
- view->SetFocusable(true);
-
- GetContentsView()->AddChildView(button);
- button->SetBounds(10, 10, 200, 30);
- GetContentsView()->AddChildView(view);
- RunPendingMessages();
-
- TestFocusChangeListener listener;
- AddFocusChangeListener(&listener);
-
- view->RequestFocus();
- RunPendingMessages();
-
- // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
- views::View* null_view = NULL;
-
- // Deacivate the window, it should store its focus.
- SimulateDeactivateWindow();
- EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
- EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view));
- EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(view, null_view));
- listener.ClearFocusChanges();
-
- // Reactivate, focus should come-back to the previously focused view.
- SimulateActivateWindow();
- EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
- EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view));
- listener.ClearFocusChanges();
-
- // Same test with a NativeControl.
- button->RequestFocus();
- SimulateDeactivateWindow();
- EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
- EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view, button));
- EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(button, null_view));
- listener.ClearFocusChanges();
-
- SimulateActivateWindow();
- EXPECT_EQ(button, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
- EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, button));
- listener.ClearFocusChanges();
-
- /*
- // Now test that while the window is inactive we can change the focused view
- // (we do that in several places).
- SimulateDeactivateWindow();
- // TODO: would have to mock the window being inactive (with a TestWidgetWin
- // that would return false on IsActive()).
- GetFocusManager()->SetFocusedView(view);
- ::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_ACTIVE, NULL);
-
- EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
- EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(button, null_view));
- EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(null_view, view));
- */
-}
-
-// Test that the focus manager is created successfully for the first view
-// window parented to a native dialog.
-TEST_F(FocusManagerTest, CreationForNativeRoot) {
- // Create a window class.
- WNDCLASSEX class_ex;
- memset(&class_ex, 0, sizeof(class_ex));
- class_ex.cbSize = sizeof(WNDCLASSEX);
- class_ex.lpfnWndProc = &DefWindowProc;
- class_ex.lpszClassName = L"TestWindow";
- ATOM atom = RegisterClassEx(&class_ex);
- ASSERT_TRUE(atom);
-
- // Create a native dialog window.
- HWND hwnd = CreateWindowEx(0, class_ex.lpszClassName, NULL,
- WS_OVERLAPPEDWINDOW, 0, 0, 200, 200,
- NULL, NULL, NULL, NULL);
- ASSERT_TRUE(hwnd);
-
- // Create a view window parented to native dialog.
- scoped_ptr<Widget> widget1(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.parent = hwnd;
- params.bounds = gfx::Rect(0, 0, 100, 100);
- params.top_level = true; // This is top level in views hierarchy.
- widget1->Init(params);
-
- // Get the focus manager directly from the first window. Should exist
- // because the first window is the root widget.
- views::FocusManager* focus_manager1 = widget1->GetFocusManager();
- EXPECT_TRUE(focus_manager1);
-
- // Create another view window parented to the first view window.
- scoped_ptr<Widget> widget2(new Widget);
- params.parent = widget1->GetNativeView();
- params.top_level = false; // This is child widget.
- widget2->Init(params);
-
- // Access the shared focus manager directly from the second window.
- views::FocusManager* focus_manager2 = widget2->GetFocusManager();
- EXPECT_EQ(focus_manager2, focus_manager1);
-
- // Access the shared focus manager indirectly from the first window handle.
- gfx::NativeWindow native_window = widget1->GetNativeWindow();
- views::Widget* widget =
- views::Widget::GetWidgetForNativeWindow(native_window);
- EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
-
- // Access the shared focus manager indirectly from the second window handle.
- native_window = widget2->GetNativeWindow();
- widget = views::Widget::GetWidgetForNativeWindow(native_window);
- EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
-
- // Access the shared focus manager indirectly from the first view handle.
- gfx::NativeView native_view = widget1->GetNativeView();
- widget = views::Widget::GetTopLevelWidgetForNativeView(native_view);
- EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
-
- // Access the shared focus manager indirectly from the second view handle.
- native_view = widget2->GetNativeView();
- widget = views::Widget::GetTopLevelWidgetForNativeView(native_view);
- EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
-
- DestroyWindow(hwnd);
-}
-
-// Tests that the keyup messages are eaten for accelerators.
-// Windows-only, Windows is the only platform that handles accelerators in
-// AcceleratorHandler. NativeWidgetAura::OnKeyEvent handles them in other
-// configurations.
-TEST_F(FocusManagerTest, IgnoreKeyupForAccelerators) {
- FocusManager* focus_manager = GetFocusManager();
- MessageTrackingView* mtv = new MessageTrackingView();
- mtv->AddAccelerator(ui::Accelerator(ui::VKEY_0, ui::EF_NONE));
- mtv->AddAccelerator(ui::Accelerator(ui::VKEY_1, ui::EF_NONE));
- GetContentsView()->AddChildView(mtv);
- focus_manager->SetFocusedView(mtv);
-
- // First send a non-accelerator key sequence.
- PostKeyDown(ui::VKEY_9);
- PostKeyUp(ui::VKEY_9);
- AcceleratorHandler accelerator_handler;
- scoped_ptr<base::RunLoop> run_loop(new base::RunLoop(&accelerator_handler));
- run_loop->RunUntilIdle();
- // Make sure we get a key-up and key-down.
- ASSERT_EQ(1U, mtv->keys_pressed().size());
- EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[0]);
- ASSERT_EQ(1U, mtv->keys_released().size());
- EXPECT_EQ(ui::VKEY_9, mtv->keys_released()[0]);
- EXPECT_FALSE(mtv->accelerator_pressed());
- mtv->Reset();
-
- // Same thing with repeat and more than one key at once.
- PostKeyDown(ui::VKEY_9);
- PostKeyDown(ui::VKEY_9);
- PostKeyDown(ui::VKEY_8);
- PostKeyDown(ui::VKEY_9);
- PostKeyDown(ui::VKEY_7);
- PostKeyUp(ui::VKEY_9);
- PostKeyUp(ui::VKEY_7);
- PostKeyUp(ui::VKEY_8);
- run_loop.reset(new base::RunLoop(&accelerator_handler));
- run_loop->RunUntilIdle();
- // Make sure we get a key-up and key-down.
- ASSERT_EQ(5U, mtv->keys_pressed().size());
- EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[0]);
- EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[1]);
- EXPECT_EQ(ui::VKEY_8, mtv->keys_pressed()[2]);
- EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[3]);
- EXPECT_EQ(ui::VKEY_7, mtv->keys_pressed()[4]);
- ASSERT_EQ(3U, mtv->keys_released().size());
- EXPECT_EQ(ui::VKEY_9, mtv->keys_released()[0]);
- EXPECT_EQ(ui::VKEY_7, mtv->keys_released()[1]);
- EXPECT_EQ(ui::VKEY_8, mtv->keys_released()[2]);
- EXPECT_FALSE(mtv->accelerator_pressed());
- mtv->Reset();
-
- // Now send an accelerator key sequence.
- PostKeyDown(ui::VKEY_0);
- PostKeyUp(ui::VKEY_0);
- run_loop.reset(new base::RunLoop(&accelerator_handler));
- run_loop->RunUntilIdle();
- EXPECT_TRUE(mtv->keys_pressed().empty());
- EXPECT_TRUE(mtv->keys_released().empty());
- EXPECT_TRUE(mtv->accelerator_pressed());
- mtv->Reset();
-
- // Same thing with repeat and more than one key at once.
- PostKeyDown(ui::VKEY_0);
- PostKeyDown(ui::VKEY_1);
- PostKeyDown(ui::VKEY_1);
- PostKeyDown(ui::VKEY_0);
- PostKeyDown(ui::VKEY_0);
- PostKeyUp(ui::VKEY_1);
- PostKeyUp(ui::VKEY_0);
- run_loop.reset(new base::RunLoop(&accelerator_handler));
- run_loop->RunUntilIdle();
- EXPECT_TRUE(mtv->keys_pressed().empty());
- EXPECT_TRUE(mtv->keys_released().empty());
- EXPECT_TRUE(mtv->accelerator_pressed());
- mtv->Reset();
-}
-
-} // namespace views
diff --git a/chromium/ui/views/focus/focus_traversal_unittest.cc b/chromium/ui/views/focus/focus_traversal_unittest.cc
index c3e8159a5fa..6f0ba34ecb2 100644
--- a/chromium/ui/views/focus/focus_traversal_unittest.cc
+++ b/chromium/ui/views/focus/focus_traversal_unittest.cc
@@ -20,11 +20,12 @@
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/tabbed_pane/tabbed_pane.h"
#include "ui/views/controls/textfield/textfield.h"
-#include "ui/views/focus/accelerator_handler.h"
#include "ui/views/focus/focus_manager_test.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"
+using base::ASCIIToUTF16;
+
namespace views {
namespace {
@@ -89,7 +90,7 @@ class DummyComboboxModel : public ui::ComboboxModel {
public:
// Overridden from ui::ComboboxModel:
virtual int GetItemCount() const OVERRIDE { return 10; }
- virtual string16 GetItemAt(int index) OVERRIDE {
+ virtual base::string16 GetItemAt(int index) OVERRIDE {
return ASCIIToUTF16("Item ") + base::IntToString16(index);
}
};
@@ -157,11 +158,7 @@ class BorderView : public NativeViewHost {
if (!widget_) {
widget_ = new Widget;
Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
-#if defined(OS_WIN) || defined(USE_AURA)
params.parent = details.parent->GetWidget()->GetNativeView();
-#else
- NOTREACHED();
-#endif
widget_->Init(params);
widget_->SetFocusTraversableParentView(this);
widget_->SetContentsView(child_);
@@ -294,7 +291,7 @@ void FocusTraversalTest::InitContentView() {
cb->set_id(kTopCheckBoxID);
left_container_ = new PaneView();
- left_container_->set_border(Border::CreateSolidBorder(1, SK_ColorBLACK));
+ left_container_->SetBorder(Border::CreateSolidBorder(1, SK_ColorBLACK));
left_container_->set_background(
Background::CreateSolidBackground(240, 240, 240));
left_container_->set_id(kLeftContainerID);
@@ -361,7 +358,7 @@ void FocusTraversalTest::InitContentView() {
y += label_height + gap_between_labels;
LabelButton* button = new LabelButton(NULL, ASCIIToUTF16("Click me"));
- button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON);
+ button->SetStyle(Button::STYLE_BUTTON);
button->SetBounds(label_x, y + 10, 80, 30);
button->set_id(kFruitButtonID);
left_container_->AddChildView(button);
@@ -379,7 +376,7 @@ void FocusTraversalTest::InitContentView() {
left_container_->AddChildView(combobox);
right_container_ = new PaneView();
- right_container_->set_border(Border::CreateSolidBorder(1, SK_ColorBLACK));
+ right_container_->SetBorder(Border::CreateSolidBorder(1, SK_ColorBLACK));
right_container_->set_background(
Background::CreateSolidBackground(240, 240, 240));
right_container_->set_id(kRightContainerID);
@@ -410,7 +407,7 @@ void FocusTraversalTest::InitContentView() {
y += radio_button_height + gap_between_radio_buttons;
View* inner_container = new View();
- inner_container->set_border(Border::CreateSolidBorder(1, SK_ColorBLACK));
+ inner_container->SetBorder(Border::CreateSolidBorder(1, SK_ColorBLACK));
inner_container->set_background(
Background::CreateSolidBackground(230, 230, 230));
inner_container->set_id(kInnerContainerID);
@@ -457,7 +454,7 @@ void FocusTraversalTest::InitContentView() {
y = 250;
int width = 60;
button = new LabelButton(NULL, ASCIIToUTF16("OK"));
- button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON);
+ button->SetStyle(Button::STYLE_BUTTON);
button->set_id(kOKButtonID);
button->SetIsDefault(true);
@@ -465,13 +462,13 @@ void FocusTraversalTest::InitContentView() {
button->SetBounds(150, y, width, 30);
button = new LabelButton(NULL, ASCIIToUTF16("Cancel"));
- button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON);
+ button->SetStyle(Button::STYLE_BUTTON);
button->set_id(kCancelButtonID);
GetContentsView()->AddChildView(button);
button->SetBounds(220, y, width, 30);
button = new LabelButton(NULL, ASCIIToUTF16("Help"));
- button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON);
+ button->SetStyle(Button::STYLE_BUTTON);
button->set_id(kHelpButtonID);
GetContentsView()->AddChildView(button);
button->SetBounds(290, y, width, 30);
@@ -525,7 +522,7 @@ void FocusTraversalTest::InitContentView() {
text_field->set_id(kSearchTextfieldID);
button = new LabelButton(NULL, ASCIIToUTF16("Search"));
- button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON);
+ button->SetStyle(Button::STYLE_BUTTON);
contents->AddChildView(button);
button->SetBounds(112, 5, 60, 30);
button->set_id(kSearchButtonID);
@@ -549,12 +546,12 @@ void FocusTraversalTest::InitContentView() {
contents->set_background(Background::CreateSolidBackground(SK_ColorBLUE));
contents->set_id(kThumbnailContainerID);
button = new LabelButton(NULL, ASCIIToUTF16("Star"));
- button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON);
+ button->SetStyle(Button::STYLE_BUTTON);
contents->AddChildView(button);
button->SetBounds(5, 5, 50, 30);
button->set_id(kThumbnailStarID);
button = new LabelButton(NULL, ASCIIToUTF16("SuperStar"));
- button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON);
+ button->SetStyle(Button::STYLE_BUTTON);
contents->AddChildView(button);
button->SetBounds(60, 5, 100, 30);
button->set_id(kThumbnailSuperStarID);
@@ -579,9 +576,6 @@ TEST_F(FocusTraversalTest, NormalTraversal) {
kSearchTextfieldID, kSearchButtonID, kHelpLinkID,
kThumbnailContainerID, kThumbnailStarID, kThumbnailSuperStarID };
- // Uncomment the following line to manually test the UI of this test.
- // base::RunLoop(new AcceleratorHandler()).Run();
-
// Let's traverse the whole focus hierarchy (several times, to make sure it
// loops OK).
GetFocusManager()->ClearFocus();
@@ -631,9 +625,6 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
v->SetEnabled(false);
}
- // Uncomment the following line to manually test the UI of this test.
- // base::RunLoop(new AcceleratorHandler()).Run();
-
View* focused_view;
// Let's do one traversal (several times, to make sure it loops ok).
GetFocusManager()->ClearFocus();
@@ -682,9 +673,6 @@ TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) {
v->SetVisible(false);
}
- // Uncomment the following line to manually test the UI of this test.
- // base::RunLoop(new AcceleratorHandler()).Run();
-
View* focused_view;
// Let's do one traversal (several times, to make sure it loops ok).
GetFocusManager()->ClearFocus();
diff --git a/chromium/ui/views/focus/view_storage.h b/chromium/ui/views/focus/view_storage.h
index 629aec1cbb9..5e36f3c5e9b 100644
--- a/chromium/ui/views/focus/view_storage.h
+++ b/chromium/ui/views/focus/view_storage.h
@@ -17,7 +17,7 @@ template <typename T> struct DefaultSingletonTraits;
// used for example in the FocusManager to store/restore focused views when the
// main window becomes active/inactive.
// It automatically removes a view from the storage if the view is removed from
-// the tree hierarchy.
+// the tree hierarchy or when the view is destroyed, which ever comes first.
//
// To use it, you first need to create a view storage id that can then be used
// to store/retrieve views.