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

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

Issue 8711003: Enable WebUI ScreenLocker for aura by abstracting lock window. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reviewer suggestions. Created 9 years 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/webui_screen_locker.h" 5 #include "chrome/browser/chromeos/login/lock_window_gtk.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>
11 11
12 // Evil hack to undo X11 evil #define. 12 // Evil hack to undo X11 evil #define.
13 #undef None 13 #undef None
14 #undef Status 14 #undef Status
15 15
(...skipping 11 matching lines...) Expand all
27 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 27 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
28 #include "chrome/common/chrome_notification_types.h" 28 #include "chrome/common/chrome_notification_types.h"
29 #include "chrome/common/url_constants.h" 29 #include "chrome/common/url_constants.h"
30 #include "content/browser/renderer_host/render_widget_host_view.h" 30 #include "content/browser/renderer_host/render_widget_host_view.h"
31 #include "content/public/browser/notification_service.h" 31 #include "content/public/browser/notification_service.h"
32 #include "content/public/browser/notification_types.h" 32 #include "content/public/browser/notification_types.h"
33 #include "ui/base/l10n/l10n_util.h" 33 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/x/x11_util.h" 34 #include "ui/base/x/x11_util.h"
35 #include "ui/gfx/screen.h" 35 #include "ui/gfx/screen.h"
36 #include "ui/views/widget/native_widget_gtk.h" 36 #include "ui/views/widget/native_widget_gtk.h"
37 #include "ui/views/widget/widget.h"
37 38
38 namespace { 39 namespace {
39 40
40 // URL which corresponds to the login WebUI.
41 const char kLoginURL[] = "chrome://oobe/login";
42
43 // The maximum duration for which locker should try to grab the keyboard and 41 // The maximum duration for which locker should try to grab the keyboard and
44 // mouse and its interval for regrabbing on failure. 42 // mouse and its interval for regrabbing on failure.
45 const int kMaxGrabFailureSec = 30; 43 const int kMaxGrabFailureSec = 30;
46 const int64 kRetryGrabIntervalMs = 500; 44 const int64 kRetryGrabIntervalMs = 500;
47 45
48 // Maximum number of times we'll try to grab the keyboard and mouse before 46 // Maximum number of times we'll try to grab the keyboard and mouse before
49 // giving up. If we hit the limit, Chrome exits and the session is terminated. 47 // giving up. If we hit the limit, Chrome exits and the session is terminated.
50 const int kMaxGrabFailures = kMaxGrabFailureSec * 1000 / kRetryGrabIntervalMs; 48 const int kMaxGrabFailures = kMaxGrabFailureSec * 1000 / kRetryGrabIntervalMs;
51 49
52 // A ScreenLock window that covers entire screen to keep the keyboard
53 // focus/events inside the grab widget.
54 class LockWindow : public views::NativeWidgetGtk {
55 public:
56 explicit LockWindow(chromeos::WebUIScreenLocker* webui_screen_locker)
57 : views::NativeWidgetGtk(new views::Widget),
58 toplevel_focus_widget_(NULL),
59 webui_screen_locker_(webui_screen_locker) {
60 EnableDoubleBuffer(true);
61 }
62
63 virtual gboolean OnButtonPress(GtkWidget* widget,
64 GdkEventButton* event) OVERRIDE {
65 // Never propagate mouse events to parent.
66 return true;
67 }
68
69 virtual void OnDestroy(GtkWidget* object) OVERRIDE {
70 VLOG(1) << "OnDestroy: LockWindow destroyed";
71 views::NativeWidgetGtk::OnDestroy(object);
72 }
73
74 virtual void ClearNativeFocus() OVERRIDE {
75 DCHECK(toplevel_focus_widget_);
76 gtk_widget_grab_focus(toplevel_focus_widget_);
77 }
78
79 virtual void HandleGtkGrabBroke() OVERRIDE {
80 webui_screen_locker_->HandleGtkGrabBroke();
81 }
82
83 // Sets the widget to move the focus to when clearning the native
84 // widget's focus.
85 void set_toplevel_focus_widget(GtkWidget* widget) {
86 gtk_widget_set_can_focus(widget, TRUE);
87 toplevel_focus_widget_ = widget;
88 }
89
90 private:
91 // The widget we set focus to when clearning the focus on native
92 // widget. Gdk input is grabbed in WebUIScreenLocker, and resetting the focus
93 // by using gtk_window_set_focus seems to confuse gtk and doesn't let focus
94 // move to native widget under this.
95 GtkWidget* toplevel_focus_widget_;
96
97 // The WebUI screen locker.
98 chromeos::WebUIScreenLocker* webui_screen_locker_;
99
100 DISALLOW_COPY_AND_ASSIGN(LockWindow);
101 };
102
103 // Define separate methods for each error code so that stack trace 50 // Define separate methods for each error code so that stack trace
104 // will tell which error the grab failed with. 51 // will tell which error the grab failed with.
105 void FailedWithGrabAlreadyGrabbed() { 52 void FailedWithGrabAlreadyGrabbed() {
106 LOG(FATAL) << "Grab already grabbed"; 53 LOG(FATAL) << "Grab already grabbed";
107 } 54 }
108 void FailedWithGrabInvalidTime() { 55 void FailedWithGrabInvalidTime() {
109 LOG(FATAL) << "Grab invalid time"; 56 LOG(FATAL) << "Grab invalid time";
110 } 57 }
111 void FailedWithGrabNotViewable() { 58 void FailedWithGrabNotViewable() {
112 LOG(FATAL) << "Grab not viewable"; 59 LOG(FATAL) << "Grab not viewable";
113 } 60 }
114 void FailedWithGrabFrozen() { 61 void FailedWithGrabFrozen() {
115 LOG(FATAL) << "Grab frozen"; 62 LOG(FATAL) << "Grab frozen";
116 } 63 }
117 void FailedWithUnknownError() { 64 void FailedWithUnknownError() {
118 LOG(FATAL) << "Grab uknown"; 65 LOG(FATAL) << "Grab uknown";
119 } 66 }
120 67
121 } // namespace 68 } // namespace
122 69
123 namespace chromeos { 70 namespace chromeos {
124 71
72 LockWindow* LockWindow::Create() {
73 return new LockWindowGtk();
74 }
75
125 //////////////////////////////////////////////////////////////////////////////// 76 ////////////////////////////////////////////////////////////////////////////////
126 // WebUIScreenLocker implementation. 77 // LockWindowGtk implementation.
127 78
128 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker) 79 void LockWindowGtk::SetContentsView(views::View* content) {
129 : ScreenLockerDelegate(screen_locker), 80 lock_window_->SetContentsView(content);
81 }
82
83 void LockWindowGtk::Show(DOMView* dom_view) {
84 lock_window_->Show();
85 // Grab on the RenderWidgetHostView hosting the WebUI login screen.
86 grab_widget_ = dom_view->dom_contents()->tab_contents()->
87 GetRenderWidgetHostView()->GetNativeView();
88 ClearGtkGrab();
89
90 // Call this after lock_window_->Show(); otherwise the 1st invocation
91 // of gdk_xxx_grab() will always fail.
92 TryGrabAllInputs();
93
94 // Add the window to its own group so that its grab won't be stolen if
95 // gtk_grab_add() gets called on behalf on a non-screen-locker widget (e.g.
96 // a modal dialog) -- see http://crosbug.com/8999. We intentionally do this
97 // after calling ClearGtkGrab(), as want to be in the default window group
98 // then so we can break any existing GTK grabs.
99 GtkWindowGroup* window_group = gtk_window_group_new();
100 gtk_window_group_add_window(window_group,
101 GTK_WINDOW(lock_window_->GetNativeView()));
102 g_object_unref(window_group);
103 }
104
105 views::Widget* LockWindowGtk::GetWidget() {
106 return views::NativeWidgetGtk::GetWidget();
107 }
108
109 gboolean LockWindowGtk::OnButtonPress(GtkWidget* widget,
110 GdkEventButton* event) {
111 // Never propagate mouse events to parent.
112 return true;
113 }
114
115 void LockWindowGtk::OnDestroy(GtkWidget* object) {
116 VLOG(1) << "OnDestroy: LockWindow destroyed";
117 views::NativeWidgetGtk::OnDestroy(object);
118 }
119
120 void LockWindowGtk::ClearNativeFocus() {
121 gtk_widget_grab_focus(window_contents());
122 }
123
124 ////////////////////////////////////////////////////////////////////////////////
125 // LockWindowGtk private:
126
127 LockWindowGtk::LockWindowGtk()
128 : views::NativeWidgetGtk(new views::Widget),
129 lock_window_(NULL),
130 grab_widget_(NULL),
130 drawn_(false), 131 drawn_(false),
131 input_grabbed_(false), 132 input_grabbed_(false),
132 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 133 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
133 grab_failure_count_(0), 134 grab_failure_count_(0),
134 kbd_grab_status_(GDK_GRAB_INVALID_TIME), 135 kbd_grab_status_(GDK_GRAB_INVALID_TIME),
135 mouse_grab_status_(GDK_GRAB_INVALID_TIME) { 136 mouse_grab_status_(GDK_GRAB_INVALID_TIME) {
137 Init();
136 } 138 }
137 139
138 void WebUIScreenLocker::LockScreen(bool unlock_on_input) { 140 LockWindowGtk::~LockWindowGtk() {
141 }
142
143 void LockWindowGtk::Init() {
139 static const GdkColor kGdkBlack = {0, 0, 0, 0}; 144 static const GdkColor kGdkBlack = {0, 0, 0, 0};
145 EnableDoubleBuffer(true);
140 146
141 gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(NULL)); 147 gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(NULL));
142 148
143 LockWindow* lock_window = new LockWindow(this); 149 lock_window_ = GetWidget();
144 lock_window_ = lock_window->GetWidget();
145 views::Widget::InitParams params( 150 views::Widget::InitParams params(
146 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 151 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
147 params.bounds = bounds; 152 params.bounds = bounds;
148 params.native_widget = lock_window; 153 params.native_widget = this;
149 lock_window_->Init(params); 154 lock_window_->Init(params);
150 gtk_widget_modify_bg( 155 gtk_widget_modify_bg(
151 lock_window_->GetNativeView(), GTK_STATE_NORMAL, &kGdkBlack); 156 lock_window_->GetNativeView(), GTK_STATE_NORMAL, &kGdkBlack);
152 157
153 g_signal_connect(lock_window_->GetNativeView(), "client-event", 158 g_signal_connect(lock_window_->GetNativeView(), "client-event",
154 G_CALLBACK(OnClientEventThunk), this); 159 G_CALLBACK(OnClientEventThunk), this);
155 160
156 // TODO(flackr): Obscure the screen with black / a screensaver if
157 // unlock_on_input.
158 DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView())); 161 DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView()));
159 WmIpc::instance()->SetWindowType( 162 WmIpc::instance()->SetWindowType(
160 lock_window_->GetNativeView(), 163 lock_window_->GetNativeView(),
161 WM_IPC_WINDOW_CHROME_SCREEN_LOCKER, 164 WM_IPC_WINDOW_CHROME_SCREEN_LOCKER,
162 NULL); 165 NULL);
163
164 WebUILoginView::Init(lock_window_);
165 lock_window_->SetContentsView(this);
166 lock_window_->Show();
167 OnWindowCreated();
168 LoadURL(GURL(kLoginURL));
169 // User list consisting of a single logged-in user.
170 UserList users(1, &chromeos::UserManager::Get()->logged_in_user());
171 login_display_.reset(new WebUILoginDisplay(this));
172 login_display_->set_background_bounds(bounds);
173 login_display_->set_parent_window(
174 GTK_WINDOW(lock_window_->GetNativeView()));
175 login_display_->Init(users, false, false);
176
177 static_cast<OobeUI*>(GetWebUI())->ShowSigninScreen(login_display_.get());
178
179 registrar_.Add(this,
180 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
181 content::NotificationService::AllSources());
182
183 ClearGtkGrab();
184
185 // Call this after lock_window_->Show(); otherwise the 1st invocation
186 // of gdk_xxx_grab() will always fail.
187 TryGrabAllInputs();
188
189 // Add the window to its own group so that its grab won't be stolen if
190 // gtk_grab_add() gets called on behalf on a non-screen-locker widget (e.g.
191 // a modal dialog) -- see http://crosbug.com/8999. We intentionally do this
192 // after calling ClearGtkGrab(), as want to be in the default window group
193 // then so we can break any existing GTK grabs.
194 GtkWindowGroup* window_group = gtk_window_group_new();
195 gtk_window_group_add_window(window_group,
196 GTK_WINDOW(lock_window_->GetNativeView()));
197 g_object_unref(window_group);
198
199 lock_window->set_toplevel_focus_widget(lock_window->window_contents());
200 } 166 }
201 167
202 void WebUIScreenLocker::OnGrabInputs() { 168 void LockWindowGtk::OnGrabInputs() {
203 DVLOG(1) << "OnGrabInputs"; 169 DVLOG(1) << "OnGrabInputs";
204 input_grabbed_ = true; 170 input_grabbed_ = true;
205 if (drawn_) 171 if (drawn_ && observer_)
206 ScreenLockReady(); 172 observer_->OnLockWindowReady();
207 } 173 }
208 174
209 void WebUIScreenLocker::OnWindowManagerReady() { 175 void LockWindowGtk::OnWindowManagerReady() {
210 DVLOG(1) << "OnClientEvent: drawn for lock"; 176 DVLOG(1) << "OnClientEvent: drawn for lock";
211 drawn_ = true; 177 drawn_ = true;
212 if (input_grabbed_) 178 if (input_grabbed_ && observer_)
213 ScreenLockReady(); 179 observer_->OnLockWindowReady();
214 } 180 }
215 181
216 void WebUIScreenLocker::ScreenLockReady() { 182 void LockWindowGtk::ClearGtkGrab() {
217 ScreenLockerDelegate::ScreenLockReady();
218 SetInputEnabled(true);
219 }
220
221 void WebUIScreenLocker::ClearGtkGrab() {
222 GtkWidget* current_grab_window; 183 GtkWidget* current_grab_window;
223 // Grab gtk input first so that the menu holding gtk grab will 184 // Grab gtk input first so that the menu holding gtk grab will
224 // close itself. 185 // close itself.
225 gtk_grab_add(webui_login_->native_view()); 186 gtk_grab_add(grab_widget_);
226 187
227 // Make sure there is no gtk grab widget so that gtk simply propagates 188 // Make sure there is no gtk grab widget so that gtk simply propagates
228 // an event. GTK maintains grab widgets in a linked-list, so we need to 189 // an event. GTK maintains grab widgets in a linked-list, so we need to
229 // remove until it's empty. 190 // remove until it's empty.
230 while ((current_grab_window = gtk_grab_get_current()) != NULL) 191 while ((current_grab_window = gtk_grab_get_current()) != NULL)
231 gtk_grab_remove(current_grab_window); 192 gtk_grab_remove(current_grab_window);
232 } 193 }
233 194
234 void WebUIScreenLocker::TryGrabAllInputs() { 195 void LockWindowGtk::TryGrabAllInputs() {
235 // Grab on the RenderWidgetHostView hosting the WebUI login screen.
236 GdkWindow* grab_widget = webui_login_->dom_contents()->tab_contents()->
237 GetRenderWidgetHostView()->GetNativeView()->window;
238 // Grab x server so that we can atomically grab and take 196 // Grab x server so that we can atomically grab and take
239 // action when grab fails. 197 // action when grab fails.
240 gdk_x11_grab_server(); 198 gdk_x11_grab_server();
241 gtk_grab_add(webui_login_->native_view()); 199 gtk_grab_add(grab_widget_);
242 if (kbd_grab_status_ != GDK_GRAB_SUCCESS) 200 if (kbd_grab_status_ != GDK_GRAB_SUCCESS)
243 kbd_grab_status_ = gdk_keyboard_grab(grab_widget, FALSE, GDK_CURRENT_TIME); 201 kbd_grab_status_ = gdk_keyboard_grab(grab_widget_->window,
202 FALSE,
203 GDK_CURRENT_TIME);
244 if (mouse_grab_status_ != GDK_GRAB_SUCCESS) { 204 if (mouse_grab_status_ != GDK_GRAB_SUCCESS) {
245 mouse_grab_status_ = 205 mouse_grab_status_ =
246 gdk_pointer_grab(grab_widget, 206 gdk_pointer_grab(grab_widget_->window,
247 FALSE, 207 FALSE,
248 static_cast<GdkEventMask>( 208 static_cast<GdkEventMask>(
249 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | 209 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
250 GDK_POINTER_MOTION_MASK), 210 GDK_POINTER_MOTION_MASK),
251 NULL, 211 NULL,
252 NULL, 212 NULL,
253 GDK_CURRENT_TIME); 213 GDK_CURRENT_TIME);
254 } 214 }
255 if ((kbd_grab_status_ != GDK_GRAB_SUCCESS || 215 if ((kbd_grab_status_ != GDK_GRAB_SUCCESS ||
256 mouse_grab_status_ != GDK_GRAB_SUCCESS) && 216 mouse_grab_status_ != GDK_GRAB_SUCCESS) &&
257 grab_failure_count_++ < kMaxGrabFailures) { 217 grab_failure_count_++ < kMaxGrabFailures) {
258 LOG(WARNING) << "Failed to grab inputs. Trying again in " 218 LOG(WARNING) << "Failed to grab inputs. Trying again in "
259 << kRetryGrabIntervalMs << " ms: kbd=" 219 << kRetryGrabIntervalMs << " ms: kbd="
260 << kbd_grab_status_ << ", mouse=" << mouse_grab_status_; 220 << kbd_grab_status_ << ", mouse=" << mouse_grab_status_;
261 TryUngrabOtherClients(); 221 TryUngrabOtherClients();
262 gdk_x11_ungrab_server(); 222 gdk_x11_ungrab_server();
263 MessageLoop::current()->PostDelayedTask( 223 MessageLoop::current()->PostDelayedTask(
264 FROM_HERE, 224 FROM_HERE,
265 base::Bind(&WebUIScreenLocker::TryGrabAllInputs, 225 base::Bind(&LockWindowGtk::TryGrabAllInputs,
266 weak_factory_.GetWeakPtr()), 226 weak_factory_.GetWeakPtr()),
267 kRetryGrabIntervalMs); 227 kRetryGrabIntervalMs);
268 } else { 228 } else {
269 gdk_x11_ungrab_server(); 229 gdk_x11_ungrab_server();
270 GdkGrabStatus status = kbd_grab_status_; 230 GdkGrabStatus status = kbd_grab_status_;
271 if (status == GDK_GRAB_SUCCESS) { 231 if (status == GDK_GRAB_SUCCESS) {
272 status = mouse_grab_status_; 232 status = mouse_grab_status_;
273 } 233 }
274 switch (status) { 234 switch (status) {
275 case GDK_GRAB_SUCCESS: 235 case GDK_GRAB_SUCCESS:
(...skipping 12 matching lines...) Expand all
288 break; 248 break;
289 default: 249 default:
290 FailedWithUnknownError(); 250 FailedWithUnknownError();
291 break; 251 break;
292 } 252 }
293 DVLOG(1) << "Grab Success"; 253 DVLOG(1) << "Grab Success";
294 OnGrabInputs(); 254 OnGrabInputs();
295 } 255 }
296 } 256 }
297 257
298 void WebUIScreenLocker::TryUngrabOtherClients() { 258 void LockWindowGtk::TryUngrabOtherClients() {
299 #if !defined(NDEBUG) 259 #if !defined(NDEBUG)
300 { 260 {
301 int event_base, error_base; 261 int event_base, error_base;
302 int major, minor; 262 int major, minor;
303 // Make sure we have XTest extension. 263 // Make sure we have XTest extension.
304 DCHECK(XTestQueryExtension(ui::GetXDisplay(), 264 DCHECK(XTestQueryExtension(ui::GetXDisplay(),
305 &event_base, &error_base, 265 &event_base, &error_base,
306 &major, &minor)); 266 &major, &minor));
307 } 267 }
308 #endif 268 #endif
309 269
310 // The following code is an attempt to grab inputs by closing 270 // The following code is an attempt to grab inputs by closing
311 // supposedly opened menu. This happens when a plugin has a menu 271 // supposedly opened menu. This happens when a plugin has a menu
312 // opened. 272 // opened.
313 if (mouse_grab_status_ == GDK_GRAB_ALREADY_GRABBED || 273 if (mouse_grab_status_ == GDK_GRAB_ALREADY_GRABBED ||
314 mouse_grab_status_ == GDK_GRAB_FROZEN) { 274 mouse_grab_status_ == GDK_GRAB_FROZEN) {
315 // Successfully grabbed the keyboard, but pointer is still 275 // Successfully grabbed the keyboard, but pointer is still
316 // grabbed by other client. Another attempt to close supposedly 276 // grabbed by other client. Another attempt to close supposedly
317 // opened menu by emulating keypress at the left top corner. 277 // opened menu by emulating keypress at the left top corner.
318 Display* display = ui::GetXDisplay(); 278 Display* display = ui::GetXDisplay();
319 Window root, child; 279 Window root, child;
320 int root_x, root_y, win_x, winy; 280 int root_x, root_y, win_x, winy;
321 unsigned int mask; 281 unsigned int mask;
322 XQueryPointer(display, 282 XQueryPointer(display,
323 ui::GetX11WindowFromGtkWidget( 283 ui::GetX11WindowFromGtkWidget(
324 static_cast<LockWindow*>(lock_window_->native_widget())->
325 window_contents()), 284 window_contents()),
326 &root, &child, &root_x, &root_y, 285 &root, &child, &root_x, &root_y,
327 &win_x, &winy, &mask); 286 &win_x, &winy, &mask);
328 XTestFakeMotionEvent(display, -1, -10000, -10000, CurrentTime); 287 XTestFakeMotionEvent(display, -1, -10000, -10000, CurrentTime);
329 XTestFakeButtonEvent(display, 1, True, CurrentTime); 288 XTestFakeButtonEvent(display, 1, True, CurrentTime);
330 XTestFakeButtonEvent(display, 1, False, CurrentTime); 289 XTestFakeButtonEvent(display, 1, False, CurrentTime);
331 // Move the pointer back. 290 // Move the pointer back.
332 XTestFakeMotionEvent(display, -1, root_x, root_y, CurrentTime); 291 XTestFakeMotionEvent(display, -1, root_x, root_y, CurrentTime);
333 XFlush(display); 292 XFlush(display);
334 } else if (kbd_grab_status_ == GDK_GRAB_ALREADY_GRABBED || 293 } else if (kbd_grab_status_ == GDK_GRAB_ALREADY_GRABBED ||
335 kbd_grab_status_ == GDK_GRAB_FROZEN) { 294 kbd_grab_status_ == GDK_GRAB_FROZEN) {
336 // Successfully grabbed the pointer, but keyboard is still grabbed 295 // Successfully grabbed the pointer, but keyboard is still grabbed
337 // by other client. Another attempt to close supposedly opened 296 // by other client. Another attempt to close supposedly opened
338 // menu by emulating escape key. Such situation must be very 297 // menu by emulating escape key. Such situation must be very
339 // rare, but handling this just in case 298 // rare, but handling this just in case
340 Display* display = ui::GetXDisplay(); 299 Display* display = ui::GetXDisplay();
341 KeyCode escape = XKeysymToKeycode(display, XK_Escape); 300 KeyCode escape = XKeysymToKeycode(display, XK_Escape);
342 XTestFakeKeyEvent(display, escape, True, CurrentTime); 301 XTestFakeKeyEvent(display, escape, True, CurrentTime);
343 XTestFakeKeyEvent(display, escape, False, CurrentTime); 302 XTestFakeKeyEvent(display, escape, False, CurrentTime);
344 XFlush(display); 303 XFlush(display);
345 } 304 }
346 } 305 }
347 306
348 void WebUIScreenLocker::HandleGtkGrabBroke() { 307 void LockWindowGtk::HandleGtkGrabBroke() {
349 // Input should never be stolen from ScreenLocker once it's 308 // Input should never be stolen from ScreenLocker once it's
350 // grabbed. If this happens, it's a bug and has to be fixed. We 309 // grabbed. If this happens, it's a bug and has to be fixed. We
351 // let chrome crash to get a crash report and dump, and 310 // let chrome crash to get a crash report and dump, and
352 // SessionManager will terminate the session to logout. 311 // SessionManager will terminate the session to logout.
353 CHECK_NE(GDK_GRAB_SUCCESS, kbd_grab_status_); 312 CHECK_NE(GDK_GRAB_SUCCESS, kbd_grab_status_);
354 CHECK_NE(GDK_GRAB_SUCCESS, mouse_grab_status_); 313 CHECK_NE(GDK_GRAB_SUCCESS, mouse_grab_status_);
355 } 314 }
356 315
357 void WebUIScreenLocker::OnAuthenticate() { 316 void LockWindowGtk::OnClientEvent(GtkWidget* widge, GdkEventClient* event) {
358 }
359
360 void WebUIScreenLocker::SetInputEnabled(bool enabled) {
361 login_display_->SetUIEnabled(enabled);
362 SetStatusAreaEnabled(enabled);
363 }
364
365 void WebUIScreenLocker::SetSignoutEnabled(bool enabled) {
366 // TODO(flackr): Implement (crbug.com/105267).
367 NOTIMPLEMENTED();
368 }
369
370 void WebUIScreenLocker::ShowErrorMessage(const string16& message,
371 bool sign_out_only) {
372 // TODO(flackr): Use login_display_ to show error message (requires either
373 // adding a method to display error strings or strictly passing error ids:
374 // crbug.com/105267).
375 base::FundamentalValue login_attempts_value(0);
376 base::StringValue error_message(message);
377 base::StringValue help_link("");
378 base::FundamentalValue help_id(0);
379 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.showSignInError",
380 login_attempts_value,
381 error_message,
382 help_link,
383 help_id);
384 }
385
386 void WebUIScreenLocker::ShowCaptchaAndErrorMessage(const GURL& captcha_url,
387 const string16& message) {
388 ShowErrorMessage(message, true);
389 }
390
391 void WebUIScreenLocker::ClearErrors() {
392 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
393 }
394
395 WebUIScreenLocker::~WebUIScreenLocker() {
396 DCHECK(lock_window_);
397 lock_window_->Close();
398 }
399
400 void WebUIScreenLocker::OnClientEvent(GtkWidget* widge, GdkEventClient* event) {
401 WmIpc::Message msg; 317 WmIpc::Message msg;
402 WmIpc::instance()->DecodeMessage(*event, &msg); 318 WmIpc::instance()->DecodeMessage(*event, &msg);
403 if (msg.type() == WM_IPC_MESSAGE_CHROME_NOTIFY_SCREEN_REDRAWN_FOR_LOCK) 319 if (msg.type() == WM_IPC_MESSAGE_CHROME_NOTIFY_SCREEN_REDRAWN_FOR_LOCK)
404 OnWindowManagerReady(); 320 OnWindowManagerReady();
405 } 321 }
406 322
407 ////////////////////////////////////////////////////////////////////////////////
408 // WebUIScreenLocker, content::NotificationObserver implementation:
409
410 void WebUIScreenLocker::Observe(
411 int type,
412 const content::NotificationSource& source,
413 const content::NotificationDetails& details) {
414 if (type != chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED)
415 return;
416
417 const User& user = *content::Details<User>(details).ptr();
418 login_display_->OnUserImageChanged(user);
419 }
420
421 ////////////////////////////////////////////////////////////////////////////////
422 // WebUIScreenLocker, LoginDisplay::Delegate implementation:
423
424 void WebUIScreenLocker::CreateAccount() {
425 NOTREACHED();
426 }
427
428 string16 WebUIScreenLocker::GetConnectedNetworkName() {
429 return GetCurrentNetworkName(CrosLibrary::Get()->GetNetworkLibrary());
430 }
431
432 void WebUIScreenLocker::FixCaptivePortal() {
433 NOTREACHED();
434 }
435
436 void WebUIScreenLocker::CompleteLogin(const std::string& username,
437 const std::string& password) {
438 NOTREACHED();
439 }
440
441 void WebUIScreenLocker::Login(const std::string& username,
442 const std::string& password) {
443 DCHECK(username == chromeos::UserManager::Get()->logged_in_user().email());
444
445 chromeos::ScreenLocker::default_screen_locker()->Authenticate(
446 ASCIIToUTF16(password));
447 }
448
449 void WebUIScreenLocker::LoginAsGuest() {
450 NOTREACHED();
451 }
452
453 void WebUIScreenLocker::OnUserSelected(const std::string& username) {
454 }
455
456 void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
457 NOTREACHED();
458 }
459
460 } // namespace chromeos 323 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698