summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/login/screen_lock_view.cc29
-rw-r--r--chrome/browser/chromeos/login/screen_locker.cc50
-rw-r--r--views/focus/focus_manager_gtk.cc10
-rw-r--r--views/widget/widget_gtk.cc9
-rw-r--r--views/widget/widget_gtk.h3
5 files changed, 87 insertions, 14 deletions
diff --git a/chrome/browser/chromeos/login/screen_lock_view.cc b/chrome/browser/chromeos/login/screen_lock_view.cc
index 3c879d7..c554f30 100644
--- a/chrome/browser/chromeos/login/screen_lock_view.cc
+++ b/chrome/browser/chromeos/login/screen_lock_view.cc
@@ -23,6 +23,31 @@
namespace chromeos {
+namespace {
+
+// A Textfield for password, which also sets focus to itself
+// when a mouse is clicked on it. This is necessary in screen locker
+// as mouse events are grabbed in the screen locker.
+class PasswordField : public views::Textfield {
+ public:
+ PasswordField()
+ : views::Textfield(views::Textfield::STYLE_PASSWORD) {
+ set_text_to_display_when_empty(
+ l10n_util::GetStringUTF16(IDS_LOGIN_EMPTY_PASSWORD_TEXT));
+ }
+
+ // views::View overrides.
+ virtual bool OnMousePressed(const views::MouseEvent& e) {
+ RequestFocus();
+ return false;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PasswordField);
+};
+
+} // namespace
+
using views::GridLayout;
using login::kBorderSize;
@@ -45,9 +70,7 @@ void ScreenLockView::Init() {
views::Background::CreateSolidBackground(login::kBackgroundColor));
// Password field.
- password_field_ = new views::Textfield(views::Textfield::STYLE_PASSWORD);
- password_field_->set_text_to_display_when_empty(
- l10n_util::GetStringUTF16(IDS_LOGIN_EMPTY_PASSWORD_TEXT));
+ password_field_ = new PasswordField();
password_field_->SetController(this);
// Unlock button.
diff --git a/chrome/browser/chromeos/login/screen_locker.cc b/chrome/browser/chromeos/login/screen_locker.cc
index 1ea943a..e8d156a 100644
--- a/chrome/browser/chromeos/login/screen_locker.cc
+++ b/chrome/browser/chromeos/login/screen_locker.cc
@@ -145,6 +145,50 @@ class ScreenLockObserver : public chromeos::ScreenLockLibrary::Observer,
DISALLOW_COPY_AND_ASSIGN(ScreenLockObserver);
};
+// A ScreenLock window that covers entire screen to keeps the keyboard
+// focus/events inside the grab widget.
+class LockWindow : public views::WidgetGtk {
+ public:
+ LockWindow()
+ : WidgetGtk(views::WidgetGtk::TYPE_POPUP),
+ toplevel_focus_widget_(NULL) {
+ }
+
+ // GTK propagates key events from parents to children.
+ // Make sure LockWindow will never handle key events.
+ virtual gboolean OnKeyPress(GtkWidget* widget, GdkEventKey* event) {
+ // Don't handle key event in the lock window.
+ return false;
+ }
+
+ virtual gboolean OnKeyRelease(GtkWidget* widget, GdkEventKey* event) {
+ // Don't handle key event in the lock window.
+ return false;
+ }
+
+ virtual void ClearNativeFocus() {
+ DCHECK(toplevel_focus_widget_);
+ gtk_widget_grab_focus(toplevel_focus_widget_);
+ }
+
+ // Sets the widget to move the focus to when clearning the native
+ // widget's focus.
+ void set_toplevel_focus_widget(GtkWidget* widget) {
+ GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS);
+ toplevel_focus_widget_ = widget;
+ }
+
+ private:
+ // The widget we set focus to when clearning the focus on native
+ // widget. In screen locker, gdk input is grabbed in GrabWidget,
+ // and resetting the focus by using gtk_window_set_focus seems to
+ // confuse gtk and doesn't let focus move to native widget under
+ // GrabWidget.
+ GtkWidget* toplevel_focus_widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(LockWindow);
+};
+
// A child widget that grabs both keyboard and pointer input.
// TODO(oshima): catch grab-broke event and quit if it ever happenes.
class GrabWidget : public views::WidgetGtk {
@@ -352,7 +396,8 @@ ScreenLocker::ScreenLocker(const UserManager::User& user)
void ScreenLocker::Init(const gfx::Rect& bounds) {
// TODO(oshima): Figure out which UI to keep and remove in the background.
views::View* screen = new BackgroundView();
- lock_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
+ LockWindow* lock_window = new LockWindow();
+ lock_window_ = lock_window;
lock_window_->Init(NULL, bounds);
g_signal_connect(lock_window_->GetNativeView(),
"map-event",
@@ -383,7 +428,7 @@ void ScreenLocker::Init(const gfx::Rect& bounds) {
lock_widget_->MakeTransparent();
lock_widget_->InitWithWidget(lock_window_,
gfx::Rect((bounds.width() - size.width()) / 2,
- (bounds.height() - size.width()) / 2,
+ (bounds.height() - size.height()) / 2,
size.width(),
size.height()));
if (screen_lock_view_)
@@ -397,6 +442,7 @@ void ScreenLocker::Init(const gfx::Rect& bounds) {
NULL, false);
gdk_window_set_back_pixmap(lock_widget_->GetNativeView()->window,
NULL, false);
+ lock_window->set_toplevel_focus_widget(lock_widget_->window_contents());
}
void ScreenLocker::OnLoginFailure(const std::string& error) {
diff --git a/views/focus/focus_manager_gtk.cc b/views/focus/focus_manager_gtk.cc
index a52a6d9..6e9dbcf 100644
--- a/views/focus/focus_manager_gtk.cc
+++ b/views/focus/focus_manager_gtk.cc
@@ -13,15 +13,7 @@
namespace views {
void FocusManager::ClearNativeFocus() {
- GtkWidget* gtk_widget = widget_->GetNativeView();
- if (!gtk_widget) {
- NOTREACHED();
- return;
- }
-
- // Since only top-level WidgetGtk have a focus manager, the native view is
- // expected to be a GtkWindow.
- gtk_window_set_focus(GTK_WINDOW(gtk_widget), NULL);
+ static_cast<WidgetGtk*>(widget_)->ClearNativeFocus();
}
void FocusManager::FocusNativeView(gfx::NativeView native_view) {
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index 2f21358..c3b0814 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -849,6 +849,15 @@ View* WidgetGtk::GetFocusTraversableParentView() {
return NULL;
}
+void WidgetGtk::ClearNativeFocus() {
+ DCHECK(type_ != TYPE_CHILD);
+ if (!GetNativeView()) {
+ NOTREACHED();
+ return;
+ }
+ gtk_window_set_focus(GTK_WINDOW(GetNativeView()), NULL);
+}
+
////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, protected:
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index 3b95140..816a263 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -194,6 +194,9 @@ class WidgetGtk
virtual FocusTraversable* GetFocusTraversableParent();
virtual View* GetFocusTraversableParentView();
+ // Clears the focus on the native widget having the focus.
+ virtual void ClearNativeFocus();
+
protected:
// If widget containes another widget, translates event coordinates to the
// contained widget's coordinates, else returns original event coordinates.