OLD | NEW |
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 Loading... |
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 LockWindowGtk* window = new LockWindowGtk(); |
| 74 return window; |
| 75 } |
| 76 |
125 //////////////////////////////////////////////////////////////////////////////// | 77 //////////////////////////////////////////////////////////////////////////////// |
126 // WebUIScreenLocker implementation. | 78 // LockWindowGtk implementation. |
127 | 79 |
128 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker) | 80 LockWindowGtk::LockWindowGtk() |
129 : ScreenLockerDelegate(screen_locker), | 81 : views::NativeWidgetGtk(new views::Widget), |
| 82 lock_window_(NULL), |
| 83 grab_widget_(NULL), |
130 drawn_(false), | 84 drawn_(false), |
131 input_grabbed_(false), | 85 input_grabbed_(false), |
132 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 86 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
133 grab_failure_count_(0), | 87 grab_failure_count_(0), |
134 kbd_grab_status_(GDK_GRAB_INVALID_TIME), | 88 kbd_grab_status_(GDK_GRAB_INVALID_TIME), |
135 mouse_grab_status_(GDK_GRAB_INVALID_TIME) { | 89 mouse_grab_status_(GDK_GRAB_INVALID_TIME) { |
| 90 Init(); |
136 } | 91 } |
137 | 92 |
138 void WebUIScreenLocker::LockScreen(bool unlock_on_input) { | 93 void LockWindowGtk::SetContentsView(views::View* content) { |
| 94 lock_window_->SetContentsView(content); |
| 95 } |
| 96 |
| 97 void LockWindowGtk::Show(DOMView* dom_view) { |
| 98 lock_window_->Show(); |
| 99 // Grab on the RenderWidgetHostView hosting the WebUI login screen. |
| 100 grab_widget_ = dom_view->dom_contents()->tab_contents()-> |
| 101 GetRenderWidgetHostView()->GetNativeView(); |
| 102 ClearGtkGrab(); |
| 103 |
| 104 // Call this after lock_window_->Show(); otherwise the 1st invocation |
| 105 // of gdk_xxx_grab() will always fail. |
| 106 TryGrabAllInputs(); |
| 107 |
| 108 // Add the window to its own group so that its grab won't be stolen if |
| 109 // gtk_grab_add() gets called on behalf on a non-screen-locker widget (e.g. |
| 110 // a modal dialog) -- see http://crosbug.com/8999. We intentionally do this |
| 111 // after calling ClearGtkGrab(), as want to be in the default window group |
| 112 // then so we can break any existing GTK grabs. |
| 113 GtkWindowGroup* window_group = gtk_window_group_new(); |
| 114 gtk_window_group_add_window(window_group, |
| 115 GTK_WINDOW(lock_window_->GetNativeView())); |
| 116 g_object_unref(window_group); |
| 117 } |
| 118 |
| 119 views::Widget* LockWindowGtk::GetWidget() { |
| 120 return views::NativeWidgetGtk::GetWidget(); |
| 121 } |
| 122 |
| 123 gboolean LockWindowGtk::OnButtonPress(GtkWidget* widget, |
| 124 GdkEventButton* event) { |
| 125 // Never propagate mouse events to parent. |
| 126 return true; |
| 127 } |
| 128 |
| 129 void LockWindowGtk::OnDestroy(GtkWidget* object) { |
| 130 VLOG(1) << "OnDestroy: LockWindow destroyed"; |
| 131 views::NativeWidgetGtk::OnDestroy(object); |
| 132 } |
| 133 |
| 134 void LockWindowGtk::ClearNativeFocus() { |
| 135 gtk_widget_grab_focus(window_contents()); |
| 136 } |
| 137 |
| 138 //////////////////////////////////////////////////////////////////////////////// |
| 139 // LockWindowGtk private: |
| 140 |
| 141 void LockWindowGtk::Init() { |
139 static const GdkColor kGdkBlack = {0, 0, 0, 0}; | 142 static const GdkColor kGdkBlack = {0, 0, 0, 0}; |
| 143 EnableDoubleBuffer(true); |
140 | 144 |
141 gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(NULL)); | 145 gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(NULL)); |
142 | 146 |
143 LockWindow* lock_window = new LockWindow(this); | 147 lock_window_ = GetWidget(); |
144 lock_window_ = lock_window->GetWidget(); | |
145 views::Widget::InitParams params( | 148 views::Widget::InitParams params( |
146 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); | 149 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
147 params.bounds = bounds; | 150 params.bounds = bounds; |
148 params.native_widget = lock_window; | 151 params.native_widget = this; |
149 lock_window_->Init(params); | 152 lock_window_->Init(params); |
150 gtk_widget_modify_bg( | 153 gtk_widget_modify_bg( |
151 lock_window_->GetNativeView(), GTK_STATE_NORMAL, &kGdkBlack); | 154 lock_window_->GetNativeView(), GTK_STATE_NORMAL, &kGdkBlack); |
152 | 155 |
153 g_signal_connect(lock_window_->GetNativeView(), "client-event", | 156 g_signal_connect(lock_window_->GetNativeView(), "client-event", |
154 G_CALLBACK(OnClientEventThunk), this); | 157 G_CALLBACK(OnClientEventThunk), this); |
155 | 158 |
156 // TODO(flackr): Obscure the screen with black / a screensaver if | |
157 // unlock_on_input. | |
158 DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView())); | 159 DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView())); |
159 WmIpc::instance()->SetWindowType( | 160 WmIpc::instance()->SetWindowType( |
160 lock_window_->GetNativeView(), | 161 lock_window_->GetNativeView(), |
161 WM_IPC_WINDOW_CHROME_SCREEN_LOCKER, | 162 WM_IPC_WINDOW_CHROME_SCREEN_LOCKER, |
162 NULL); | 163 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 } | 164 } |
201 | 165 |
202 void WebUIScreenLocker::OnGrabInputs() { | 166 void LockWindowGtk::OnGrabInputs() { |
203 DVLOG(1) << "OnGrabInputs"; | 167 DVLOG(1) << "OnGrabInputs"; |
204 input_grabbed_ = true; | 168 input_grabbed_ = true; |
205 if (drawn_) | 169 if (drawn_ && observer_) |
206 ScreenLockReady(); | 170 observer_->OnLockWindowReady(); |
207 } | 171 } |
208 | 172 |
209 void WebUIScreenLocker::OnWindowManagerReady() { | 173 void LockWindowGtk::OnWindowManagerReady() { |
210 DVLOG(1) << "OnClientEvent: drawn for lock"; | 174 DVLOG(1) << "OnClientEvent: drawn for lock"; |
211 drawn_ = true; | 175 drawn_ = true; |
212 if (input_grabbed_) | 176 if (input_grabbed_ && observer_) |
213 ScreenLockReady(); | 177 observer_->OnLockWindowReady(); |
214 } | 178 } |
215 | 179 |
216 void WebUIScreenLocker::ScreenLockReady() { | 180 void LockWindowGtk::ClearGtkGrab() { |
217 ScreenLockerDelegate::ScreenLockReady(); | |
218 SetInputEnabled(true); | |
219 } | |
220 | |
221 void WebUIScreenLocker::ClearGtkGrab() { | |
222 GtkWidget* current_grab_window; | 181 GtkWidget* current_grab_window; |
223 // Grab gtk input first so that the menu holding gtk grab will | 182 // Grab gtk input first so that the menu holding gtk grab will |
224 // close itself. | 183 // close itself. |
225 gtk_grab_add(webui_login_->native_view()); | 184 gtk_grab_add(grab_widget_); |
226 | 185 |
227 // Make sure there is no gtk grab widget so that gtk simply propagates | 186 // 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 | 187 // an event. GTK maintains grab widgets in a linked-list, so we need to |
229 // remove until it's empty. | 188 // remove until it's empty. |
230 while ((current_grab_window = gtk_grab_get_current()) != NULL) | 189 while ((current_grab_window = gtk_grab_get_current()) != NULL) |
231 gtk_grab_remove(current_grab_window); | 190 gtk_grab_remove(current_grab_window); |
232 } | 191 } |
233 | 192 |
234 void WebUIScreenLocker::TryGrabAllInputs() { | 193 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 | 194 // Grab x server so that we can atomically grab and take |
239 // action when grab fails. | 195 // action when grab fails. |
240 gdk_x11_grab_server(); | 196 gdk_x11_grab_server(); |
241 gtk_grab_add(webui_login_->native_view()); | 197 gtk_grab_add(grab_widget_); |
242 if (kbd_grab_status_ != GDK_GRAB_SUCCESS) | 198 if (kbd_grab_status_ != GDK_GRAB_SUCCESS) |
243 kbd_grab_status_ = gdk_keyboard_grab(grab_widget, FALSE, GDK_CURRENT_TIME); | 199 kbd_grab_status_ = gdk_keyboard_grab(grab_widget_->window, |
| 200 FALSE, |
| 201 GDK_CURRENT_TIME); |
244 if (mouse_grab_status_ != GDK_GRAB_SUCCESS) { | 202 if (mouse_grab_status_ != GDK_GRAB_SUCCESS) { |
245 mouse_grab_status_ = | 203 mouse_grab_status_ = |
246 gdk_pointer_grab(grab_widget, | 204 gdk_pointer_grab(grab_widget_->window, |
247 FALSE, | 205 FALSE, |
248 static_cast<GdkEventMask>( | 206 static_cast<GdkEventMask>( |
249 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | | 207 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
250 GDK_POINTER_MOTION_MASK), | 208 GDK_POINTER_MOTION_MASK), |
251 NULL, | 209 NULL, |
252 NULL, | 210 NULL, |
253 GDK_CURRENT_TIME); | 211 GDK_CURRENT_TIME); |
254 } | 212 } |
255 if ((kbd_grab_status_ != GDK_GRAB_SUCCESS || | 213 if ((kbd_grab_status_ != GDK_GRAB_SUCCESS || |
256 mouse_grab_status_ != GDK_GRAB_SUCCESS) && | 214 mouse_grab_status_ != GDK_GRAB_SUCCESS) && |
257 grab_failure_count_++ < kMaxGrabFailures) { | 215 grab_failure_count_++ < kMaxGrabFailures) { |
258 LOG(WARNING) << "Failed to grab inputs. Trying again in " | 216 LOG(WARNING) << "Failed to grab inputs. Trying again in " |
259 << kRetryGrabIntervalMs << " ms: kbd=" | 217 << kRetryGrabIntervalMs << " ms: kbd=" |
260 << kbd_grab_status_ << ", mouse=" << mouse_grab_status_; | 218 << kbd_grab_status_ << ", mouse=" << mouse_grab_status_; |
261 TryUngrabOtherClients(); | 219 TryUngrabOtherClients(); |
262 gdk_x11_ungrab_server(); | 220 gdk_x11_ungrab_server(); |
263 MessageLoop::current()->PostDelayedTask( | 221 MessageLoop::current()->PostDelayedTask( |
264 FROM_HERE, | 222 FROM_HERE, |
265 base::Bind(&WebUIScreenLocker::TryGrabAllInputs, | 223 base::Bind(&LockWindowGtk::TryGrabAllInputs, |
266 weak_factory_.GetWeakPtr()), | 224 weak_factory_.GetWeakPtr()), |
267 kRetryGrabIntervalMs); | 225 kRetryGrabIntervalMs); |
268 } else { | 226 } else { |
269 gdk_x11_ungrab_server(); | 227 gdk_x11_ungrab_server(); |
270 GdkGrabStatus status = kbd_grab_status_; | 228 GdkGrabStatus status = kbd_grab_status_; |
271 if (status == GDK_GRAB_SUCCESS) { | 229 if (status == GDK_GRAB_SUCCESS) { |
272 status = mouse_grab_status_; | 230 status = mouse_grab_status_; |
273 } | 231 } |
274 switch (status) { | 232 switch (status) { |
275 case GDK_GRAB_SUCCESS: | 233 case GDK_GRAB_SUCCESS: |
(...skipping 12 matching lines...) Expand all Loading... |
288 break; | 246 break; |
289 default: | 247 default: |
290 FailedWithUnknownError(); | 248 FailedWithUnknownError(); |
291 break; | 249 break; |
292 } | 250 } |
293 DVLOG(1) << "Grab Success"; | 251 DVLOG(1) << "Grab Success"; |
294 OnGrabInputs(); | 252 OnGrabInputs(); |
295 } | 253 } |
296 } | 254 } |
297 | 255 |
298 void WebUIScreenLocker::TryUngrabOtherClients() { | 256 void LockWindowGtk::TryUngrabOtherClients() { |
299 #if !defined(NDEBUG) | 257 #if !defined(NDEBUG) |
300 { | 258 { |
301 int event_base, error_base; | 259 int event_base, error_base; |
302 int major, minor; | 260 int major, minor; |
303 // Make sure we have XTest extension. | 261 // Make sure we have XTest extension. |
304 DCHECK(XTestQueryExtension(ui::GetXDisplay(), | 262 DCHECK(XTestQueryExtension(ui::GetXDisplay(), |
305 &event_base, &error_base, | 263 &event_base, &error_base, |
306 &major, &minor)); | 264 &major, &minor)); |
307 } | 265 } |
308 #endif | 266 #endif |
309 | 267 |
310 // The following code is an attempt to grab inputs by closing | 268 // The following code is an attempt to grab inputs by closing |
311 // supposedly opened menu. This happens when a plugin has a menu | 269 // supposedly opened menu. This happens when a plugin has a menu |
312 // opened. | 270 // opened. |
313 if (mouse_grab_status_ == GDK_GRAB_ALREADY_GRABBED || | 271 if (mouse_grab_status_ == GDK_GRAB_ALREADY_GRABBED || |
314 mouse_grab_status_ == GDK_GRAB_FROZEN) { | 272 mouse_grab_status_ == GDK_GRAB_FROZEN) { |
315 // Successfully grabbed the keyboard, but pointer is still | 273 // Successfully grabbed the keyboard, but pointer is still |
316 // grabbed by other client. Another attempt to close supposedly | 274 // grabbed by other client. Another attempt to close supposedly |
317 // opened menu by emulating keypress at the left top corner. | 275 // opened menu by emulating keypress at the left top corner. |
318 Display* display = ui::GetXDisplay(); | 276 Display* display = ui::GetXDisplay(); |
319 Window root, child; | 277 Window root, child; |
320 int root_x, root_y, win_x, winy; | 278 int root_x, root_y, win_x, winy; |
321 unsigned int mask; | 279 unsigned int mask; |
322 XQueryPointer(display, | 280 XQueryPointer(display, |
323 ui::GetX11WindowFromGtkWidget( | 281 ui::GetX11WindowFromGtkWidget( |
324 static_cast<LockWindow*>(lock_window_->native_widget())-> | |
325 window_contents()), | 282 window_contents()), |
326 &root, &child, &root_x, &root_y, | 283 &root, &child, &root_x, &root_y, |
327 &win_x, &winy, &mask); | 284 &win_x, &winy, &mask); |
328 XTestFakeMotionEvent(display, -1, -10000, -10000, CurrentTime); | 285 XTestFakeMotionEvent(display, -1, -10000, -10000, CurrentTime); |
329 XTestFakeButtonEvent(display, 1, True, CurrentTime); | 286 XTestFakeButtonEvent(display, 1, True, CurrentTime); |
330 XTestFakeButtonEvent(display, 1, False, CurrentTime); | 287 XTestFakeButtonEvent(display, 1, False, CurrentTime); |
331 // Move the pointer back. | 288 // Move the pointer back. |
332 XTestFakeMotionEvent(display, -1, root_x, root_y, CurrentTime); | 289 XTestFakeMotionEvent(display, -1, root_x, root_y, CurrentTime); |
333 XFlush(display); | 290 XFlush(display); |
334 } else if (kbd_grab_status_ == GDK_GRAB_ALREADY_GRABBED || | 291 } else if (kbd_grab_status_ == GDK_GRAB_ALREADY_GRABBED || |
335 kbd_grab_status_ == GDK_GRAB_FROZEN) { | 292 kbd_grab_status_ == GDK_GRAB_FROZEN) { |
336 // Successfully grabbed the pointer, but keyboard is still grabbed | 293 // Successfully grabbed the pointer, but keyboard is still grabbed |
337 // by other client. Another attempt to close supposedly opened | 294 // by other client. Another attempt to close supposedly opened |
338 // menu by emulating escape key. Such situation must be very | 295 // menu by emulating escape key. Such situation must be very |
339 // rare, but handling this just in case | 296 // rare, but handling this just in case |
340 Display* display = ui::GetXDisplay(); | 297 Display* display = ui::GetXDisplay(); |
341 KeyCode escape = XKeysymToKeycode(display, XK_Escape); | 298 KeyCode escape = XKeysymToKeycode(display, XK_Escape); |
342 XTestFakeKeyEvent(display, escape, True, CurrentTime); | 299 XTestFakeKeyEvent(display, escape, True, CurrentTime); |
343 XTestFakeKeyEvent(display, escape, False, CurrentTime); | 300 XTestFakeKeyEvent(display, escape, False, CurrentTime); |
344 XFlush(display); | 301 XFlush(display); |
345 } | 302 } |
346 } | 303 } |
347 | 304 |
348 void WebUIScreenLocker::HandleGtkGrabBroke() { | 305 void LockWindowGtk::HandleGtkGrabBroke() { |
349 // Input should never be stolen from ScreenLocker once it's | 306 // 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 | 307 // 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 | 308 // let chrome crash to get a crash report and dump, and |
352 // SessionManager will terminate the session to logout. | 309 // SessionManager will terminate the session to logout. |
353 CHECK_NE(GDK_GRAB_SUCCESS, kbd_grab_status_); | 310 CHECK_NE(GDK_GRAB_SUCCESS, kbd_grab_status_); |
354 CHECK_NE(GDK_GRAB_SUCCESS, mouse_grab_status_); | 311 CHECK_NE(GDK_GRAB_SUCCESS, mouse_grab_status_); |
355 } | 312 } |
356 | 313 |
357 void WebUIScreenLocker::OnAuthenticate() { | 314 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; | 315 WmIpc::Message msg; |
402 WmIpc::instance()->DecodeMessage(*event, &msg); | 316 WmIpc::instance()->DecodeMessage(*event, &msg); |
403 if (msg.type() == WM_IPC_MESSAGE_CHROME_NOTIFY_SCREEN_REDRAWN_FOR_LOCK) | 317 if (msg.type() == WM_IPC_MESSAGE_CHROME_NOTIFY_SCREEN_REDRAWN_FOR_LOCK) |
404 OnWindowManagerReady(); | 318 OnWindowManagerReady(); |
405 } | 319 } |
406 | 320 |
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 | 321 } // namespace chromeos |
OLD | NEW |