Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: chrome/browser/chromeos/login/screen_locker_views.cc

Issue 8557005: Rebase the MessageBubble on the new views bubble. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync and merge again... Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/login/screen_locker_views.h" 5 #include "chrome/browser/chromeos/login/screen_locker_views.h"
6 6
7 #include <X11/extensions/XTest.h> 7 #include <X11/extensions/XTest.h>
8 #include <X11/keysym.h> 8 #include <X11/keysym.h>
9 #include <gdk/gdkkeysyms.h> 9 #include <gdk/gdkkeysyms.h>
10 #include <gdk/gdkx.h> 10 #include <gdk/gdkx.h>
(...skipping 13 matching lines...) Expand all
24 #include "chrome/browser/chromeos/status/status_area_view_chromeos.h" 24 #include "chrome/browser/chromeos/status/status_area_view_chromeos.h"
25 #include "chrome/browser/chromeos/view_ids.h" 25 #include "chrome/browser/chromeos/view_ids.h"
26 #include "chrome/browser/prefs/pref_service.h" 26 #include "chrome/browser/prefs/pref_service.h"
27 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h" 28 #include "chrome/common/pref_names.h"
29 #include "content/browser/user_metrics.h" 29 #include "content/browser/user_metrics.h"
30 #include "grit/theme_resources.h" 30 #include "grit/theme_resources.h"
31 #include "ui/base/resource/resource_bundle.h" 31 #include "ui/base/resource/resource_bundle.h"
32 #include "ui/base/x/x11_util.h" 32 #include "ui/base/x/x11_util.h"
33 #include "ui/gfx/screen.h" 33 #include "ui/gfx/screen.h"
34 #include "views/controls/textfield/textfield.h"
34 35
35 #if defined(TOOLKIT_USES_GTK) 36 #if defined(TOOLKIT_USES_GTK)
36 #include "chrome/browser/chromeos/legacy_window_manager/wm_ipc.h" 37 #include "chrome/browser/chromeos/legacy_window_manager/wm_ipc.h"
38 #include "views/widget/native_widget_gtk.h"
37 #endif 39 #endif
38 40
39 namespace { 41 namespace {
40 42
41 // The active ScreenLockerDelegate. 43 // The active ScreenLockerDelegate.
42 chromeos::ScreenLockerViews* screen_locker_view_ = NULL; 44 chromeos::ScreenLockerViews* screen_locker_view_ = NULL;
43 45
44 // The maximum duration for which locker should try to grab the keyboard and 46 // The maximum duration for which locker should try to grab the keyboard and
45 // mouse and its interval for regrabbing on failure. 47 // mouse and its interval for regrabbing on failure.
46 const int kMaxGrabFailureSec = 30; 48 const int kMaxGrabFailureSec = 30;
47 const int64 kRetryGrabIntervalMs = 500; 49 const int64 kRetryGrabIntervalMs = 500;
48 50
49 // Maximum number of times we'll try to grab the keyboard and mouse before 51 // Maximum number of times we'll try to grab the keyboard and mouse before
50 // giving up. If we hit the limit, Chrome exits and the session is terminated. 52 // giving up. If we hit the limit, Chrome exits and the session is terminated.
51 const int kMaxGrabFailures = kMaxGrabFailureSec * 1000 / kRetryGrabIntervalMs; 53 const int kMaxGrabFailures = kMaxGrabFailureSec * 1000 / kRetryGrabIntervalMs;
52 54
53 // A idle time to show the screen saver in seconds. 55 // A idle time to show the screen saver in seconds.
54 const int kScreenSaverIdleTimeout = 15; 56 const int kScreenSaverIdleTimeout = 15;
55 57
56 // A ScreenLock window that covers entire screen to keep the keyboard 58 // A ScreenLock window that covers entire screen to keep the keyboard
57 // focus/events inside the grab widget. 59 // focus/events inside the grab widget.
58 class LockWindow : public views::NativeWidgetGtk { 60 class LockWindow : public views::NativeWidgetGtk {
59 public: 61 public:
60 LockWindow() 62 LockWindow()
61 : views::NativeWidgetGtk(new views::Widget), 63 : views::NativeWidgetGtk(new views::Widget),
62 toplevel_focus_widget_(NULL) { 64 toplevel_focus_widget_(NULL) {
63 EnableDoubleBuffer(true); 65 EnableDoubleBuffer(true);
66 g_signal_connect(GetNativeView(), "client-event",
67 G_CALLBACK(OnClientEventThunk), this);
64 } 68 }
65 69
66 // GTK propagates key events from parents to children. 70 // GTK propagates key events from parents to children.
67 // Make sure LockWindow will never handle key events. 71 // Make sure LockWindow will never handle key events.
68 virtual gboolean OnEventKey(GtkWidget* widget, GdkEventKey* event) OVERRIDE { 72 virtual gboolean OnEventKey(GtkWidget* widget, GdkEventKey* event) OVERRIDE {
69 // Don't handle key event in the lock window. 73 // Don't handle key event in the lock window.
70 return false; 74 return false;
71 } 75 }
72 76
73 virtual gboolean OnButtonPress(GtkWidget* widget, 77 virtual gboolean OnButtonPress(GtkWidget* widget,
74 GdkEventButton* event) OVERRIDE { 78 GdkEventButton* event) OVERRIDE {
75 // Don't handle mouse event in the lock wnidow and 79 // Don't handle mouse event in the lock wnidow and
76 // nor propagate to child. 80 // nor propagate to child.
77 return true; 81 return true;
78 } 82 }
79 83
80 virtual void OnDestroy(GtkWidget* object) OVERRIDE { 84 virtual void OnDestroy(GtkWidget* object) OVERRIDE {
81 VLOG(1) << "OnDestroy: LockWindow destroyed"; 85 VLOG(1) << "OnDestroy: LockWindow destroyed";
82 views::NativeWidgetGtk::OnDestroy(object); 86 views::NativeWidgetGtk::OnDestroy(object);
83 } 87 }
84 88
85 virtual void ClearNativeFocus() OVERRIDE { 89 virtual void ClearNativeFocus() OVERRIDE {
86 DCHECK(toplevel_focus_widget_); 90 DCHECK(toplevel_focus_widget_);
87 gtk_widget_grab_focus(toplevel_focus_widget_); 91 gtk_widget_grab_focus(toplevel_focus_widget_);
88 } 92 }
89 93
94 // Event handler for client-event.
95 CHROMEGTK_CALLBACK_1(LockWindow, void, OnClientEvent, GdkEventClient*);
96
90 // Sets the widget to move the focus to when clearning the native 97 // Sets the widget to move the focus to when clearning the native
91 // widget's focus. 98 // widget's focus.
92 void set_toplevel_focus_widget(GtkWidget* widget) { 99 void set_toplevel_focus_widget(GtkWidget* widget) {
93 gtk_widget_set_can_focus(widget, TRUE); 100 gtk_widget_set_can_focus(widget, TRUE);
94 toplevel_focus_widget_ = widget; 101 toplevel_focus_widget_ = widget;
95 } 102 }
96 103
97 private: 104 private:
98 // The widget we set focus to when clearning the focus on native 105 // The widget we set focus to when clearning the focus on native
99 // widget. In screen locker, gdk input is grabbed in GrabWidget, 106 // widget. In screen locker, gdk input is grabbed in GrabWidget,
100 // and resetting the focus by using gtk_window_set_focus seems to 107 // and resetting the focus by using gtk_window_set_focus seems to
101 // confuse gtk and doesn't let focus move to native widget under 108 // confuse gtk and doesn't let focus move to native widget under
102 // GrabWidget. 109 // GrabWidget.
103 GtkWidget* toplevel_focus_widget_; 110 GtkWidget* toplevel_focus_widget_;
104 111
105 DISALLOW_COPY_AND_ASSIGN(LockWindow); 112 DISALLOW_COPY_AND_ASSIGN(LockWindow);
106 }; 113 };
107 114
115 void LockWindow::OnClientEvent(GtkWidget* widget, GdkEventClient* event) {
116 #if defined(TOOLKIT_USES_GTK)
117 chromeos::WmIpc::Message msg;
118 chromeos::WmIpc::instance()->DecodeMessage(*event, &msg);
119 if (msg.type() ==
120 chromeos::WM_IPC_MESSAGE_CHROME_NOTIFY_SCREEN_REDRAWN_FOR_LOCK) {
121 screen_locker_view_->OnWindowManagerReady();
122 }
123 #endif
124 }
125
108 // GrabWidget's root view to layout the ScreenLockView at the center 126 // GrabWidget's root view to layout the ScreenLockView at the center
109 // and the Shutdown button at the left top. 127 // and the Shutdown button at the left top.
110 class GrabWidgetRootView 128 class GrabWidgetRootView
111 : public views::View, 129 : public views::View,
112 public chromeos::ScreenLockerViews::ScreenLockViewContainer { 130 public chromeos::ScreenLockerViews::ScreenLockViewContainer {
113 public: 131 public:
114 explicit GrabWidgetRootView(chromeos::ScreenLockView* screen_lock_view) 132 explicit GrabWidgetRootView(chromeos::ScreenLockView* screen_lock_view)
115 : screen_lock_view_(screen_lock_view), 133 : screen_lock_view_(screen_lock_view),
116 shutdown_button_(new chromeos::ShutdownButton()) { 134 shutdown_button_(new chromeos::ShutdownButton()) {
117 shutdown_button_->Init(); 135 shutdown_button_->Init();
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 LockWindow* lock_window = new LockWindow(); 627 LockWindow* lock_window = new LockWindow();
610 lock_window_ = lock_window->GetWidget(); 628 lock_window_ = lock_window->GetWidget();
611 views::Widget::InitParams params( 629 views::Widget::InitParams params(
612 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 630 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
613 params.bounds = init_bounds; 631 params.bounds = init_bounds;
614 params.native_widget = lock_window; 632 params.native_widget = lock_window;
615 lock_window_->Init(params); 633 lock_window_->Init(params);
616 gtk_widget_modify_bg( 634 gtk_widget_modify_bg(
617 lock_window_->GetNativeView(), GTK_STATE_NORMAL, &kGdkBlack); 635 lock_window_->GetNativeView(), GTK_STATE_NORMAL, &kGdkBlack);
618 636
619 g_signal_connect(lock_window_->GetNativeView(), "client-event",
620 G_CALLBACK(OnClientEventThunk), this);
621
622 // GTK does not like zero width/height. 637 // GTK does not like zero width/height.
623 if (!unlock_on_input) { 638 if (!unlock_on_input) {
624 screen_lock_view_ = new ScreenLockView(screen_locker_); 639 screen_lock_view_ = new ScreenLockView(screen_locker_);
625 screen_lock_view_->Init(); 640 screen_lock_view_->Init();
626 screen_lock_view_->SetEnabled(false); 641 screen_lock_view_->SetEnabled(false);
627 screen_lock_view_->StartThrobber(); 642 screen_lock_view_->StartThrobber();
628 } else { 643 } else {
629 input_event_observer_.reset(new InputEventObserver(screen_locker_)); 644 input_event_observer_.reset(new InputEventObserver(screen_locker_));
630 MessageLoopForUI::current()->AddObserver(input_event_observer_.get()); 645 MessageLoopForUI::current()->AddObserver(input_event_observer_.get());
631 } 646 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 ignore_result(secondary_view_.release()); 814 ignore_result(secondary_view_.release());
800 screen_lock_view_->SetVisible(false); 815 screen_lock_view_->SetVisible(false);
801 grab_container_->SetScreenLockView(captcha_view_); 816 grab_container_->SetScreenLockView(captcha_view_);
802 background_container_->SetScreenLockView(captcha_view_); 817 background_container_->SetScreenLockView(captcha_view_);
803 captcha_view_->SetVisible(true); 818 captcha_view_->SetVisible(true);
804 // Take ScreenLockView ownership now that it's removed from grab_container_. 819 // Take ScreenLockView ownership now that it's removed from grab_container_.
805 secondary_view_.reset(screen_lock_view_); 820 secondary_view_.reset(screen_lock_view_);
806 } 821 }
807 822
808 void ScreenLockerViews::ClearErrors() { 823 void ScreenLockerViews::ClearErrors() {
809 if (error_info_) { 824 if (error_info_)
810 error_info_->Close(); 825 error_info_->GetWidget()->Close();
811 error_info_ = NULL;
812 }
813 } 826 }
814 827
815 void ScreenLockerViews::BubbleClosing(Bubble* bubble, bool closed_by_escape) { 828 void ScreenLockerViews::OnWidgetClosing(views::Widget* widget) {
829 if (!error_info_ || error_info_->GetWidget() != widget)
830 return;
831
816 error_info_ = NULL; 832 error_info_ = NULL;
817 SetSignoutEnabled(true); 833 SetSignoutEnabled(true);
818 if (mouse_event_relay_.get()) { 834 if (mouse_event_relay_.get()) {
819 MessageLoopForUI::current()->RemoveObserver(mouse_event_relay_.get()); 835 MessageLoopForUI::current()->RemoveObserver(mouse_event_relay_.get());
820 mouse_event_relay_.reset(); 836 mouse_event_relay_.reset();
821 } 837 }
822 } 838 }
823 839
824 bool ScreenLockerViews::CloseOnEscape() {
825 return true;
826 }
827
828 bool ScreenLockerViews::FadeInOnShow() {
829 return false;
830 }
831
832 void ScreenLockerViews::OnLinkActivated(size_t index) {
833 }
834
835 void ScreenLockerViews::OnCaptchaEntered(const std::string& captcha) { 840 void ScreenLockerViews::OnCaptchaEntered(const std::string& captcha) {
836 // Captcha dialog is only shown when LoginPerformer instance exists, 841 // Captcha dialog is only shown when LoginPerformer instance exists,
837 // i.e. blocking UI after password change is in place. 842 // i.e. blocking UI after password change is in place.
838 DCHECK(LoginPerformer::default_performer()); 843 DCHECK(LoginPerformer::default_performer());
839 LoginPerformer::default_performer()->set_captcha(captcha); 844 LoginPerformer::default_performer()->set_captcha(captcha);
840 845
841 // ScreenLockView ownership is passed to grab_container_. 846 // ScreenLockView ownership is passed to grab_container_.
842 // Need to save return value here so that compile 847 // Need to save return value here so that compile
843 // doesn't fail with "unused result" warning. 848 // doesn't fail with "unused result" warning.
844 ignore_result(secondary_view_.release()); 849 ignore_result(secondary_view_.release());
845 captcha_view_->SetVisible(false); 850 captcha_view_->SetVisible(false);
846 grab_container_->SetScreenLockView(screen_lock_view_); 851 grab_container_->SetScreenLockView(screen_lock_view_);
847 background_container_->SetScreenLockView(screen_lock_view_); 852 background_container_->SetScreenLockView(screen_lock_view_);
848 screen_lock_view_->SetVisible(true); 853 screen_lock_view_->SetVisible(true);
849 screen_lock_view_->ClearAndSetFocusToPassword(); 854 screen_lock_view_->ClearAndSetFocusToPassword();
850 855
851 // Take CaptchaView ownership now that it's removed from grab_container_. 856 // Take CaptchaView ownership now that it's removed from grab_container_.
852 secondary_view_.reset(captcha_view_); 857 secondary_view_.reset(captcha_view_);
853 ShowErrorMessage(postponed_error_message_, false); 858 ShowErrorMessage(postponed_error_message_, false);
854 postponed_error_message_.clear(); 859 postponed_error_message_.clear();
855 } 860 }
856 861
862 void ScreenLockerViews::OnWindowManagerReady() {
863 DVLOG(1) << "OnClientEvent: drawn for lock";
864 drawn_ = true;
865 if (input_grabbed_)
866 ScreenLockReady();
867 }
868
857 ScreenLockerViews::~ScreenLockerViews() { 869 ScreenLockerViews::~ScreenLockerViews() {
858 if (input_event_observer_.get()) 870 if (input_event_observer_.get())
859 MessageLoopForUI::current()->RemoveObserver(input_event_observer_.get()); 871 MessageLoopForUI::current()->RemoveObserver(input_event_observer_.get());
860 if (locker_input_event_observer_.get()) { 872 if (locker_input_event_observer_.get()) {
861 lock_widget_->GetFocusManager()->UnregisterAccelerator( 873 lock_widget_->GetFocusManager()->UnregisterAccelerator(
862 ui::Accelerator(ui::VKEY_ESCAPE, false, false, false), this); 874 ui::Accelerator(ui::VKEY_ESCAPE, false, false, false), this);
863 MessageLoopForUI::current()->RemoveObserver( 875 MessageLoopForUI::current()->RemoveObserver(
864 locker_input_event_observer_.get()); 876 locker_input_event_observer_.get());
865 } 877 }
866 878
867 gdk_keyboard_ungrab(GDK_CURRENT_TIME); 879 gdk_keyboard_ungrab(GDK_CURRENT_TIME);
868 gdk_pointer_ungrab(GDK_CURRENT_TIME); 880 gdk_pointer_ungrab(GDK_CURRENT_TIME);
869 881
870 DCHECK(lock_window_); 882 DCHECK(lock_window_);
871 VLOG(1) << "~ScreenLocker(): Closing ScreenLocker window."; 883 VLOG(1) << "~ScreenLocker(): Closing ScreenLocker window.";
872 lock_window_->Close(); 884 lock_window_->Close();
873 // lock_widget_ will be deleted by gtk's destroy signal. 885 // lock_widget_ will be deleted by gtk's destroy signal.
874 screen_locker_view_ = NULL; 886 screen_locker_view_ = NULL;
875 } 887 }
876 888
877 void ScreenLockerViews::OnWindowManagerReady() {
878 DVLOG(1) << "OnClientEvent: drawn for lock";
879 drawn_ = true;
880 if (input_grabbed_)
881 ScreenLockReady();
882 }
883
884 void ScreenLockerViews::ShowErrorBubble( 889 void ScreenLockerViews::ShowErrorBubble(
885 const string16& message, 890 const string16& message,
886 views::BubbleBorder::ArrowLocation arrow_location) { 891 views::BubbleBorder::ArrowLocation arrow_location) {
887 if (error_info_) 892 ClearErrors();
888 error_info_->Close();
889 893
890 gfx::Rect rect = screen_lock_view_->GetPasswordBoundsRelativeTo( 894 // TODO(nkostylev): Add help link.
891 lock_widget_->GetRootView()); 895 error_info_ = new MessageBubble(
892 gfx::Rect lock_widget_bounds = lock_widget_->GetClientAreaScreenBounds(); 896 screen_lock_view_->password_field(),
893 rect.Offset(lock_widget_bounds.x(), lock_widget_bounds.y());
894 error_info_ = MessageBubble::ShowNoGrab(
895 lock_window_,
896 rect,
897 arrow_location, 897 arrow_location,
898 ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING), 898 ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING),
899 UTF16ToWide(message), 899 message,
900 UTF16ToWide(string16()), // TODO(nkostylev): Add help link. 900 string16());
901 this); 901 MessageBubble::ShowBubble(error_info_);
902 error_info_->GetWidget()->AddObserver(this);
902 903
903 #if !defined(TOUCH_UI) 904 #if !defined(TOUCH_UI)
904 if (mouse_event_relay_.get()) 905 if (mouse_event_relay_.get())
905 MessageLoopForUI::current()->RemoveObserver(mouse_event_relay_.get()); 906 MessageLoopForUI::current()->RemoveObserver(mouse_event_relay_.get());
906 mouse_event_relay_.reset( 907 mouse_event_relay_.reset(
907 new MouseEventRelay(lock_widget_->GetNativeView()->window, 908 new MouseEventRelay(lock_widget_->GetNativeView()->window,
908 error_info_->GetNativeView()->window)); 909 error_info_->GetWidget()->GetNativeView()->window));
909 MessageLoopForUI::current()->AddObserver(mouse_event_relay_.get()); 910 MessageLoopForUI::current()->AddObserver(mouse_event_relay_.get());
910 #endif 911 #endif
911 } 912 }
912 913
913 bool ScreenLockerViews::AcceleratorPressed( 914 bool ScreenLockerViews::AcceleratorPressed(
914 const ui::Accelerator& accelerator) { 915 const ui::Accelerator& accelerator) {
915 if (!background_view_->IsScreenSaverVisible()) { 916 if (!background_view_->IsScreenSaverVisible()) {
916 screen_locker_view_->StartScreenSaver(); 917 screen_locker_view_->StartScreenSaver();
917 return true; 918 return true;
918 } 919 }
919 return false; 920 return false;
920 } 921 }
921 922
922 void ScreenLockerViews::OnClientEvent(GtkWidget* widge, GdkEventClient* event) {
923 #if defined(TOOLKIT_USES_GTK)
924 WmIpc::Message msg;
925 WmIpc::instance()->DecodeMessage(*event, &msg);
926 if (msg.type() == WM_IPC_MESSAGE_CHROME_NOTIFY_SCREEN_REDRAWN_FOR_LOCK) {
927 OnWindowManagerReady();
928 }
929 #endif
930 }
931
932 } // namespace chromeos 923 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698