summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-01 22:53:51 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-01 22:53:51 +0000
commitdc5e89230025a8202e0314410a388ad91138020c (patch)
tree41630518a44295112141de14f595c50e11fb84de
parent668dd15b25cf7fd94fede92dd140b59c62009390 (diff)
downloadchromium_src-dc5e89230025a8202e0314410a388ad91138020c.zip
chromium_src-dc5e89230025a8202e0314410a388ad91138020c.tar.gz
chromium_src-dc5e89230025a8202e0314410a388ad91138020c.tar.bz2
The FocusManager stores/restores focus when the top window becomes inactive/active.
BUG=None TEST=Run the focus manager unit-tests. Review URL: http://codereview.chromium.org/164448 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25108 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--app/resources/app_resources.grd6
-rw-r--r--chrome/chrome.gyp3
-rw-r--r--views/controls/button/native_button_gtk.cc7
-rw-r--r--views/controls/native_control_gtk.cc18
-rw-r--r--views/controls/native_control_gtk.h6
-rw-r--r--views/focus/focus_manager.cc45
-rw-r--r--views/focus/focus_manager_gtk.cc19
-rw-r--r--views/focus/focus_manager_unittest.cc95
-rw-r--r--views/view_unittest.cc46
-rw-r--r--views/views.gyp3
-rw-r--r--views/widget/root_view.cc7
-rw-r--r--views/widget/widget_gtk.cc18
-rw-r--r--views/widget/widget_gtk.h14
13 files changed, 204 insertions, 83 deletions
diff --git a/app/resources/app_resources.grd b/app/resources/app_resources.grd
index 086ebb4..9bf6b54 100644
--- a/app/resources/app_resources.grd
+++ b/app/resources/app_resources.grd
@@ -36,9 +36,9 @@
<include name="IDR_CLOSE" file="linux_close.png" type="BINDATA" />
<include name="IDR_CLOSE_H" file="linux_close_h.png" type="BINDATA" />
<include name="IDR_CLOSE_P" file="linux_close_p.png" type="BINDATA" />
- <include name="IDR_CLOSE_SA" file="close_sa.png" type="BINDATA" />
- <include name="IDR_CLOSE_SA_H" file="close_sa_h.png" type="BINDATA" />
- <include name="IDR_CLOSE_SA_P" file="close_sa_p.png" type="BINDATA" />
+ <include name="IDR_CLOSE_SA" file="linux_close.png" type="BINDATA" />
+ <include name="IDR_CLOSE_SA_H" file="linux_close_h.png" type="BINDATA" />
+ <include name="IDR_CLOSE_SA_P" file="linux_close_p.png" type="BINDATA" />
<include name="IDR_RESTORE" file="linux_restore.png" type="BINDATA" />
<include name="IDR_RESTORE_H" file="linux_restore_h.png" type="BINDATA" />
<include name="IDR_RESTORE_P" file="linux_restore_p.png" type="BINDATA" />
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 47a521b..b16ac73 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -4222,7 +4222,8 @@
['exclude', 'browser/gtk/bookmark_editor_gtk_unittest\\.cc$'],
['exclude', 'browser/gtk/go_button_gtk_unittest\\.cc$'],
['exclude', 'browser/gtk/tabs/tab_renderer_gtk_unittest\\.cc$'],
- ['exclude', 'browser/gtk/options/cookies_view_unittest\\.cc$'],
+ ['exclude', 'browser/gtk/options/cookies_view_unittest\\.cc$'],
+ ['exclude', 'browser/gtk/options/languages_page_gtk_unittest\\.cc$'],
],
}],
['OS=="mac"', {
diff --git a/views/controls/button/native_button_gtk.cc b/views/controls/button/native_button_gtk.cc
index 4ed3138..900a2b2 100644
--- a/views/controls/button/native_button_gtk.cc
+++ b/views/controls/button/native_button_gtk.cc
@@ -142,4 +142,11 @@ NativeButtonWrapper* NativeButtonWrapper::CreateCheckboxWrapper(
return new NativeCheckboxGtk(checkbox);
}
+// static
+NativeButtonWrapper* NativeButtonWrapper::CreateRadioButtonWrapper(
+ RadioButton* radio_button) {
+ NOTIMPLEMENTED();
+ return NULL;
+}
+
} // namespace views
diff --git a/views/controls/native_control_gtk.cc b/views/controls/native_control_gtk.cc
index e95278d..a13c870 100644
--- a/views/controls/native_control_gtk.cc
+++ b/views/controls/native_control_gtk.cc
@@ -7,6 +7,7 @@
#include <gtk/gtk.h>
#include "base/logging.h"
+#include "views/focus/focus_manager.h"
namespace views {
@@ -63,6 +64,23 @@ void NativeControlGtk::NativeControlCreated(GtkWidget* native_control) {
// Update the newly created GtkWdigetwith any resident enabled state.
gtk_widget_set_sensitive(native_view(), IsEnabled());
+
+ // Listen for focus change event to update the FocusManager focused view.
+ g_signal_connect(G_OBJECT(native_control), "focus-in-event",
+ G_CALLBACK(CallFocusIn), this);
+}
+
+// static
+void NativeControlGtk::CallFocusIn(GtkWidget* widget,
+ GdkEventFocus* event,
+ NativeControlGtk* control) {
+ FocusManager* focus_manager =
+ FocusManager::GetFocusManagerForNativeView(widget);
+ if (!focus_manager) {
+ NOTREACHED();
+ return;
+ }
+ focus_manager->SetFocusedView(control->focus_view());
}
} // namespace views
diff --git a/views/controls/native_control_gtk.h b/views/controls/native_control_gtk.h
index 2f0ffab..ce2f187 100644
--- a/views/controls/native_control_gtk.h
+++ b/views/controls/native_control_gtk.h
@@ -5,6 +5,8 @@
#ifndef VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_
#define VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_
+#include <gtk/gtk.h>
+
#include "views/controls/native/native_view_host.h"
namespace views {
@@ -34,6 +36,10 @@ class NativeControlGtk : public NativeViewHost {
virtual void NativeControlCreated(GtkWidget* widget);
private:
+ static void CallFocusIn(GtkWidget* widget,
+ GdkEventFocus* event,
+ NativeControlGtk* button);
+
DISALLOW_COPY_AND_ASSIGN(NativeControlGtk);
};
diff --git a/views/focus/focus_manager.cc b/views/focus/focus_manager.cc
index 1a0f7ae..dffb392 100644
--- a/views/focus/focus_manager.cc
+++ b/views/focus/focus_manager.cc
@@ -224,31 +224,32 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view,
}
void FocusManager::SetFocusedView(View* view) {
- if (focused_view_ != view) {
- View* prev_focused_view = focused_view_;
- if (focused_view_)
- focused_view_->WillLoseFocus();
-
- if (view)
- view->WillGainFocus();
-
- // Notified listeners that the focus changed.
- FocusChangeListenerList::const_iterator iter;
- for (iter = focus_change_listeners_.begin();
- iter != focus_change_listeners_.end(); ++iter) {
- (*iter)->FocusWillChange(prev_focused_view, view);
- }
+ if (focused_view_ == view)
+ return;
- focused_view_ = view;
+ View* prev_focused_view = focused_view_;
+ if (focused_view_)
+ focused_view_->WillLoseFocus();
- if (prev_focused_view)
- prev_focused_view->SchedulePaint(); // Remove focus artifacts.
+ if (view)
+ view->WillGainFocus();
- if (view) {
- view->SchedulePaint();
- view->Focus();
- view->DidGainFocus();
- }
+ // Notified listeners that the focus changed.
+ FocusChangeListenerList::const_iterator iter;
+ for (iter = focus_change_listeners_.begin();
+ iter != focus_change_listeners_.end(); ++iter) {
+ (*iter)->FocusWillChange(prev_focused_view, view);
+ }
+
+ focused_view_ = view;
+
+ if (prev_focused_view)
+ prev_focused_view->SchedulePaint(); // Remove focus artifacts.
+
+ if (view) {
+ view->SchedulePaint();
+ view->Focus();
+ view->DidGainFocus();
}
}
diff --git a/views/focus/focus_manager_gtk.cc b/views/focus/focus_manager_gtk.cc
index 8017961..eb25654 100644
--- a/views/focus/focus_manager_gtk.cc
+++ b/views/focus/focus_manager_gtk.cc
@@ -2,14 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <gtk/gtk.h>
+
#include "views/focus/focus_manager.h"
#include "base/logging.h"
+#include "views/widget/widget_gtk.h"
namespace views {
void FocusManager::ClearNativeFocus() {
- NOTIMPLEMENTED();
+ gtk_widget_grab_focus(widget_->GetNativeView());
}
void FocusManager::FocusNativeView(gfx::NativeView native_view) {
@@ -19,8 +22,18 @@ void FocusManager::FocusNativeView(gfx::NativeView native_view) {
// static
FocusManager* FocusManager::GetFocusManagerForNativeView(
gfx::NativeView native_view) {
- NOTIMPLEMENTED();
- return NULL;
+ GtkWidget* parent;
+ while ((parent = gtk_widget_get_parent(native_view)) != NULL) {
+ native_view = parent;
+ }
+ WidgetGtk* widget = WidgetGtk::GetViewForNative(native_view);
+ if (!widget) {
+ NOTREACHED();
+ return NULL;
+ }
+ FocusManager* focus_manager = widget->GetFocusManager();
+ DCHECK(focus_manager) << "no FocusManager for top level Widget";
+ return focus_manager;
}
} // namespace views
diff --git a/views/focus/focus_manager_unittest.cc b/views/focus/focus_manager_unittest.cc
index 720e9f8..215ed00 100644
--- a/views/focus/focus_manager_unittest.cc
+++ b/views/focus/focus_manager_unittest.cc
@@ -25,12 +25,10 @@
#include "views/controls/label.h"
#include "views/controls/link.h"
#include "views/controls/native/native_view_host.h"
-#if defined(OS_WIN)
+#include "views/controls/textfield/textfield.h"
#include "views/controls/scroll_view.h"
#include "views/controls/tabbed_pane/native_tabbed_pane_wrapper.h"
#include "views/controls/tabbed_pane/tabbed_pane.h"
-#include "views/controls/textfield/textfield.h"
-#endif
#include "views/focus/accelerator_handler.h"
#include "views/widget/root_view.h"
#include "views/window/window.h"
@@ -45,10 +43,10 @@
namespace views {
-#if defined(OS_WIN)
static const int kWindowWidth = 600;
static const int kWindowHeight = 500;
+#if defined(OS_WIN)
static int count = 1;
static const int kTopCheckBoxID = count++; // 1
@@ -72,37 +70,36 @@ static const int kCauliflowerButtonID = count++;
static const int kInnerContainerID = count++;
static const int kScrollViewID = count++;
-static const int kScrollContentViewID = count++; // 20
-static const int kRosettaLinkID = count++;
+static const int kRosettaLinkID = count++; // 20
static const int kStupeurEtTremblementLinkID = count++;
static const int kDinerGameLinkID = count++;
static const int kRidiculeLinkID = count++;
-static const int kClosetLinkID = count++; // 25
-static const int kVisitingLinkID = count++;
+static const int kClosetLinkID = count++;
+static const int kVisitingLinkID = count++; // 25
static const int kAmelieLinkID = count++;
static const int kJoyeuxNoelLinkID = count++;
static const int kCampingLinkID = count++;
-static const int kBriceDeNiceLinkID = count++; // 30
-static const int kTaxiLinkID = count++;
+static const int kBriceDeNiceLinkID = count++;
+static const int kTaxiLinkID = count++; // 30
static const int kAsterixLinkID = count++;
static const int kOKButtonID = count++;
static const int kCancelButtonID = count++;
-static const int kHelpButtonID = count++; // 35
+static const int kHelpButtonID = count++;
-static const int kStyleContainerID = count++;
+static const int kStyleContainerID = count++; // 35
static const int kBoldCheckBoxID = count++;
static const int kItalicCheckBoxID = count++;
static const int kUnderlinedCheckBoxID = count++;
-static const int kStyleHelpLinkID = count++; // 40
-static const int kStyleTextEditID = count++;
+static const int kStyleHelpLinkID = count++;
+static const int kStyleTextEditID = count++; // 40
static const int kSearchContainerID = count++;
static const int kSearchTextfieldID = count++;
static const int kSearchButtonID = count++;
-static const int kHelpLinkID = count++; // 45
+static const int kHelpLinkID = count++;
-static const int kThumbnailContainerID = count++;
+static const int kThumbnailContainerID = count++; // 45
static const int kThumbnailStarID = count++;
static const int kThumbnailSuperStarID = count++;
#endif
@@ -153,7 +150,8 @@ class FocusManagerTest : public testing::Test, public WindowDelegate {
#if defined(OS_WIN)
::SendMessage(native_view, WM_SETFOCUS, NULL, NULL);
#else
- NOTIMPLEMENTED();
+ gtk_widget_grab_focus(native_view);
+ message_loop()->RunAllPending();
#endif
}
@@ -177,14 +175,18 @@ class FocusManagerTest : public testing::Test, public WindowDelegate {
#if defined(OS_WIN)
::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_ACTIVE, NULL);
#else
- NOTIMPLEMENTED();
+ gboolean result;
+ g_signal_emit_by_name(G_OBJECT(window_->GetNativeWindow()),
+ "focus_in_event", 0, &result);
#endif
}
void SimulateDeactivateWindow() {
#if defined(OS_WIN)
::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_INACTIVE, NULL);
#else
- NOTIMPLEMENTED();
+ gboolean result;
+ g_signal_emit_by_name(G_OBJECT(window_->GetNativeWindow()),
+ "focus_out_event", 0, & result);
#endif
}
@@ -234,11 +236,16 @@ class BorderView : public NativeViewHost {
#if defined(OS_WIN)
WidgetWin* widget_win = new WidgetWin();
widget_win->Init(parent->GetRootView()->GetWidget()->GetNativeView(),
- gfx::Rect(0, 0, 100, 100));
+ gfx::Rect(0, 0, 0, 0));
widget_win->SetFocusTraversableParentView(this);
widget_ = widget_win;
#else
- widget_ = new WidgetGtk(WidgetGtk::TYPE_WINDOW);
+ WidgetGtk* widget_gtk = new WidgetGtk(WidgetGtk::TYPE_CHILD);
+ // TODO(jcampan): implement WidgetGtk::SetFocusTraversableParentView()
+ // widget_gtk->SetFocusTraversableParentView(this);
+ widget_ = widget_gtk;
+ widget_->Init(parent->GetRootView()->GetWidget()->GetNativeView(),
+ gfx::Rect(0, 0, 0, 0));
#endif
widget_->SetContentsView(child_);
}
@@ -266,6 +273,7 @@ class DummyComboboxModel : public ComboboxModel {
}
};
+#if defined(OS_WIN)
class FocusTraversalTest : public FocusManagerTest {
public:
~FocusTraversalTest();
@@ -472,7 +480,7 @@ void FocusTraversalTest::InitContentView() {
DCHECK(arraysize(kTitles) == arraysize(kIDs));
y = 5;
- for (int i = 0; i < arraysize(kTitles); ++i) {
+ for (size_t i = 0; i < arraysize(kTitles); ++i) {
Link* link = new Link(kTitles[i]);
link->SetHorizontalAlignment(Label::ALIGN_LEFT);
link->SetID(kIDs[i]);
@@ -579,6 +587,7 @@ void FocusTraversalTest::InitContentView() {
content_view_->AddChildView(contents);
contents->SetBounds(250, y, 200, 50);
}
+#endif
////////////////////////////////////////////////////////////////////////////////
// The tests
@@ -637,7 +646,7 @@ TEST_F(FocusManagerTest, ViewFocusCallbacks) {
content_view_->AddChildView(view2);
view1->RequestFocus();
- ASSERT_EQ(2, event_list.size());
+ ASSERT_EQ(2, static_cast<int>(event_list.size()));
EXPECT_EQ(WILL_GAIN_FOCUS, event_list[0].type);
EXPECT_EQ(kView1ID, event_list[0].view_id);
EXPECT_EQ(DID_GAIN_FOCUS, event_list[1].type);
@@ -645,7 +654,7 @@ TEST_F(FocusManagerTest, ViewFocusCallbacks) {
event_list.clear();
view2->RequestFocus();
- ASSERT_EQ(3, event_list.size());
+ ASSERT_EQ(3, static_cast<int>(event_list.size()));
EXPECT_EQ(WILL_LOSE_FOCUS, event_list[0].type);
EXPECT_EQ(kView1ID, event_list[0].view_id);
EXPECT_EQ(WILL_GAIN_FOCUS, event_list[1].type);
@@ -655,7 +664,7 @@ TEST_F(FocusManagerTest, ViewFocusCallbacks) {
event_list.clear();
GetFocusManager()->ClearFocus();
- ASSERT_EQ(1, event_list.size());
+ ASSERT_EQ(1, static_cast<int>(event_list.size()));
EXPECT_EQ(WILL_LOSE_FOCUS, event_list[0].type);
EXPECT_EQ(kView2ID, event_list[0].view_id);
}
@@ -687,17 +696,17 @@ TEST_F(FocusManagerTest, FocusChangeListener) {
AddFocusChangeListener(&listener);
view1->RequestFocus();
- ASSERT_EQ(1, listener.focus_changes().size());
+ ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(NULL, view1));
listener.ClearFocusChanges();
view2->RequestFocus();
- ASSERT_EQ(1, listener.focus_changes().size());
+ ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view1, view2));
listener.ClearFocusChanges();
GetFocusManager()->ClearFocus();
- ASSERT_EQ(1, listener.focus_changes().size());
+ ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view2, NULL));
}
@@ -729,6 +738,7 @@ class TestRadioButton : public RadioButton {
}
};
+#if defined(OS_WIN)
class TestTextfield : public Textfield {
public:
TestTextfield() { }
@@ -758,25 +768,30 @@ class TestTabbedPane : public TabbedPane {
return native_tabbed_pane_->GetTestingHandle();
}
};
+#endif
// Tests that NativeControls do set the focus View appropriately on the
// FocusManager.
TEST_F(FocusManagerTest, FocusNativeControls) {
TestNativeButton* button = new TestNativeButton(L"Press me");
TestCheckbox* checkbox = new TestCheckbox(L"Checkbox");
+#if defined(OS_WIN)
TestRadioButton* radio_button = new TestRadioButton(L"RadioButton");
TestTextfield* textfield = new TestTextfield();
TestCombobox* combobox = new TestCombobox();
TestTabbedPane* tabbed_pane = new TestTabbedPane();
TestNativeButton* tab_button = new TestNativeButton(L"tab button");
+#endif
content_view_->AddChildView(button);
content_view_->AddChildView(checkbox);
+#if defined(OS_WIN)
content_view_->AddChildView(radio_button);
content_view_->AddChildView(textfield);
content_view_->AddChildView(combobox);
content_view_->AddChildView(tabbed_pane);
tabbed_pane->AddTab(L"Awesome tab", tab_button);
+#endif
// Simulate the native view getting the native focus (such as by user click).
FocusNativeView(button->TestGetNativeControlView());
@@ -785,6 +800,7 @@ TEST_F(FocusManagerTest, FocusNativeControls) {
FocusNativeView(checkbox->TestGetNativeControlView());
EXPECT_EQ(checkbox, GetFocusManager()->GetFocusedView());
+#if defined(OS_WIN)
FocusNativeView(radio_button->TestGetNativeControlView());
EXPECT_EQ(radio_button, GetFocusManager()->GetFocusedView());
@@ -799,6 +815,7 @@ TEST_F(FocusManagerTest, FocusNativeControls) {
FocusNativeView(tab_button->TestGetNativeControlView());
EXPECT_EQ(tab_button, GetFocusManager()->GetFocusedView());
+#endif
}
// Test that when activating/deactivating the top window, the focus is stored/
@@ -809,17 +826,21 @@ TEST_F(FocusManagerTest, FocusStoreRestore) {
view->SetFocusable(true);
content_view_->AddChildView(button);
+ button->SetBounds(10, 10, 200, 30);
content_view_->AddChildView(view);
+ message_loop()->RunAllPending();
TestFocusChangeListener listener;
AddFocusChangeListener(&listener);
view->RequestFocus();
+ message_loop()->RunAllPending();
+ // MessageLoopForUI::current()->Run(new AcceleratorHandler());
// Deacivate the window, it should store its focus.
SimulateDeactivateWindow();
EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(2, listener.focus_changes().size());
+ ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(NULL, view));
EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(view, NULL));
listener.ClearFocusChanges();
@@ -827,7 +848,7 @@ TEST_F(FocusManagerTest, FocusStoreRestore) {
// Reactivate, focus should come-back to the previously focused view.
SimulateActivateWindow();
EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(1, listener.focus_changes().size());
+ ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(NULL, view));
listener.ClearFocusChanges();
@@ -835,14 +856,14 @@ TEST_F(FocusManagerTest, FocusStoreRestore) {
button->RequestFocus();
SimulateDeactivateWindow();
EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(2, listener.focus_changes().size());
+ 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));
listener.ClearFocusChanges();
SimulateActivateWindow();
EXPECT_EQ(button, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(1, listener.focus_changes().size());
+ ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(NULL, button));
listener.ClearFocusChanges();
@@ -856,12 +877,13 @@ TEST_F(FocusManagerTest, FocusStoreRestore) {
::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_ACTIVE, NULL);
EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
- ASSERT_EQ(2, listener.focus_changes().size());
+ ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(button, NULL));
EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(NULL, view));
*/
}
+#if defined(OS_WIN)
TEST_F(FocusManagerTest, ContainsView) {
View* view = new View();
scoped_ptr<View> detached_view(new View());
@@ -904,7 +926,7 @@ TEST_F(FocusTraversalTest, NormalTraversal) {
// loops OK).
GetFocusManager()->SetFocusedView(NULL);
for (int i = 0; i < 3; ++i) {
- for (int j = 0; j < arraysize(kTraversalIDs); j++) {
+ for (size_t j = 0; j < arraysize(kTraversalIDs); j++) {
GetFocusManager()->AdvanceFocus(false);
View* focused_view = GetFocusManager()->GetFocusedView();
EXPECT_TRUE(focused_view != NULL);
@@ -943,7 +965,7 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
kThumbnailSuperStarID };
// Let's disable some views.
- for (int i = 0; i < arraysize(kDisabledIDs); i++) {
+ for (size_t i = 0; i < arraysize(kDisabledIDs); i++) {
View* v = FindViewByID(kDisabledIDs[i]);
ASSERT_TRUE(v != NULL);
if (v)
@@ -958,7 +980,7 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
// Let's do one traversal (several times, to make sure it loops ok).
GetFocusManager()->SetFocusedView(NULL);
for (int i = 0; i < 3; ++i) {
- for (int j = 0; j < arraysize(kTraversalIDs); j++) {
+ for (size_t j = 0; j < arraysize(kTraversalIDs); j++) {
GetFocusManager()->AdvanceFocus(false);
focused_view = GetFocusManager()->GetFocusedView();
EXPECT_TRUE(focused_view != NULL);
@@ -979,6 +1001,7 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
}
}
}
+#endif
// Counts accelerator calls.
class TestAcceleratorTarget : public AcceleratorTarget {
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index 64b5848..9d2fa87 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -1185,3 +1185,49 @@ TEST_F(DefaultButtonTest, DialogDefaultButtonTest) {
SimularePressingEnterAndCheckDefaultButton(CANCEL);
}
#endif
+
+#if defined(OS_LINUX)
+class TestViewWithControls : public View {
+ public:
+ TestViewWithControls() {
+ button_ = new NativeButton(NULL, L"Button");
+ checkbox_ = new Checkbox(L"My checkbox");
+ text_field_ = new Textfield();
+ AddChildView(button_);
+ button_->SetBounds(0, 0, 100, 30);
+ AddChildView(checkbox_);
+ checkbox_->SetBounds(0, 100, 100, 30);
+ AddChildView(text_field_);
+ text_field_->SetBounds(0, 200, 100, 30);
+ text_field_->SetBackgroundColor(SK_ColorYELLOW);
+ text_field_->SetFont(gfx::Font::CreateFont(L"Arial", 30));
+ }
+
+ Button* button_;
+ Checkbox* checkbox_;
+ Textfield* text_field_;
+};
+
+class SimpleWindowDelegate : public WindowDelegate {
+ public:
+ SimpleWindowDelegate(View* contents) : contents_(contents) { }
+
+ virtual void DeleteDelegate() { delete this; }
+
+ virtual View* GetContentsView() { return contents_; }
+
+ private:
+ View* contents_;
+};
+
+TEST_F(ViewTest, DISABLED_Stupid) {
+ TestViewWithControls* view_with_controls = new TestViewWithControls();
+ views::Window* window =
+ views::Window::CreateChromeWindow(
+ NULL, gfx::Rect(200, 200, 500, 500),
+ new SimpleWindowDelegate(view_with_controls));
+ window->Show();
+ AcceleratorHandler accelerator_handler;
+ MessageLoopForUI::current()->Run(&accelerator_handler);
+}
+#endif
diff --git a/views/views.gyp b/views/views.gyp
index 4deb5aa..946c9bd 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -292,7 +292,6 @@
'accessibility/view_accessibility.cc',
'accessibility/view_accessibility_wrapper.cc',
'controls/scrollbar/bitmap_scroll_bar.cc',
- 'controls/button/radio_button.cc',
'controls/combo_box.cc',
'controls/hwnd_view.cc',
'controls/message_box_view.cc',
@@ -300,9 +299,7 @@
'controls/table/group_table_view.cc',
'controls/native_control.cc',
'controls/scrollbar/native_scroll_bar.cc',
- 'controls/button/radio_button.cc',
'controls/separator.cc',
- 'controls/tabbed_pane.cc',
'controls/table/table_model.cc',
'controls/table/table_view.cc',
'controls/table/group_table_view.cc',
diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc
index a0d19ca..4469051 100644
--- a/views/widget/root_view.cc
+++ b/views/widget/root_view.cc
@@ -510,19 +510,12 @@ void RootView::ProcessMouseDragCanceled() {
void RootView::FocusView(View* view) {
if (view != GetFocusedView()) {
-#if defined(OS_WIN)
FocusManager* focus_manager = GetFocusManager();
DCHECK(focus_manager) << "No Focus Manager for Window " <<
(GetWidget() ? GetWidget()->GetNativeView() : 0);
if (!focus_manager)
return;
-
- View* prev_focused_view = focus_manager->GetFocusedView();
focus_manager->SetFocusedView(view);
-#else
- // TODO(port): Port the focus manager and this goes away.
- NOTIMPLEMENTED();
-#endif
}
}
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index 7ab2c31..49720f3 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -570,6 +570,24 @@ gboolean WidgetGtk::OnButtonRelease(GtkWidget* widget, GdkEventButton* event) {
return true;
}
+gboolean WidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) {
+ if (type_ == TYPE_CHILD)
+ return false;
+
+ // The top-level window got focus, restore the last focused view.
+ focus_manager_->RestoreFocusedView();
+ return false;
+}
+
+gboolean WidgetGtk::OnFocusOut(GtkWidget* widget, GdkEventFocus* event) {
+ if (type_ == TYPE_CHILD)
+ return false;
+
+ // The top-level window lost focus, store the focused view.
+ focus_manager_->StoreFocusedView();
+ return false;
+}
+
void WidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) {
root_view_->OnPaint(event);
}
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index a7e905e..7a3738a 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -110,6 +110,9 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
virtual void WillProcessEvent(GdkEvent* event);
virtual void DidProcessEvent(GdkEvent* event);
+ // Retrieves the WidgetGtk associated with |widget|.
+ static WidgetGtk* GetViewForNative(GtkWidget* widget);
+
// Retrieves the WindowGtk associated with |widget|.
static WindowGtk* GetWindowForNative(GtkWidget* widget);
@@ -148,12 +151,8 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event);
virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event);
virtual gboolean OnButtonRelease(GtkWidget* widget, GdkEventButton* event);
- virtual gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event) {
- return false;
- }
- virtual gboolean OnFocusOut(GtkWidget* widget, GdkEventFocus* event) {
- return false;
- }
+ virtual gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event);
+ virtual gboolean OnFocusOut(GtkWidget* widget, GdkEventFocus* event);
virtual gboolean OnKeyPress(GtkWidget* widget, GdkEventKey* event);
virtual gboolean OnKeyRelease(GtkWidget* widget, GdkEventKey* event);
virtual gboolean OnScroll(GtkWidget* widget, GdkEventScroll* event) {
@@ -200,8 +199,7 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
bool ProcessMousePressed(GdkEventButton* event);
void ProcessMouseReleased(GdkEventButton* event);
- // Sets and retrieves the WidgetGtk in the userdata section of the widget.
- static WidgetGtk* GetViewForNative(GtkWidget* widget);
+ // Sets the WidgetGtk in the userdata section of the widget.
static void SetViewForNative(GtkWidget* widget, WidgetGtk* view);
static RootView* GetRootViewForWidget(GtkWidget* widget);