OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/views/widget/root_view.h" | 5 #include "chrome/views/widget/root_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
10 #include "base/base_drag_source.h" | 10 #include "base/base_drag_source.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 | 52 |
53 ///////////////////////////////////////////////////////////////////////////// | 53 ///////////////////////////////////////////////////////////////////////////// |
54 // | 54 // |
55 // RootView - constructors, destructors, initialization | 55 // RootView - constructors, destructors, initialization |
56 // | 56 // |
57 ///////////////////////////////////////////////////////////////////////////// | 57 ///////////////////////////////////////////////////////////////////////////// |
58 | 58 |
59 RootView::RootView(Widget* widget) | 59 RootView::RootView(Widget* widget) |
60 : mouse_pressed_handler_(NULL), | 60 : mouse_pressed_handler_(NULL), |
61 mouse_move_handler_(NULL), | 61 mouse_move_handler_(NULL), |
| 62 last_click_handler_(NULL), |
62 widget_(widget), | 63 widget_(widget), |
63 invalid_rect_urgent_(false), | 64 invalid_rect_urgent_(false), |
64 pending_paint_task_(NULL), | 65 pending_paint_task_(NULL), |
65 paint_task_needed_(false), | 66 paint_task_needed_(false), |
66 explicit_mouse_handler_(false), | 67 explicit_mouse_handler_(false), |
67 #if defined(OS_WIN) | 68 #if defined(OS_WIN) |
68 previous_cursor_(NULL), | 69 previous_cursor_(NULL), |
69 #endif | 70 #endif |
70 default_keyboard_hander_(NULL), | 71 default_keyboard_hander_(NULL), |
71 focus_listener_(NULL), | 72 focus_listener_(NULL), |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 Source<View>(child), | 266 Source<View>(child), |
266 Details<View>(parent)); | 267 Details<View>(parent)); |
267 } | 268 } |
268 } | 269 } |
269 | 270 |
270 void RootView::SetFocusOnMousePressed(bool f) { | 271 void RootView::SetFocusOnMousePressed(bool f) { |
271 focus_on_mouse_pressed_ = f; | 272 focus_on_mouse_pressed_ = f; |
272 } | 273 } |
273 | 274 |
274 bool RootView::OnMousePressed(const MouseEvent& e) { | 275 bool RootView::OnMousePressed(const MouseEvent& e) { |
| 276 // This function does not normally handle non-client messages except for |
| 277 // non-client double-clicks. Actually, all double-clicks are special as the |
| 278 // are formed from a single-click followed by a double-click event. When the |
| 279 // double-click event lands on a different view than its single-click part, |
| 280 // we transform it into a single-click which prevents odd things. |
| 281 if ((e.GetFlags() & MouseEvent::EF_IS_NON_CLIENT) && |
| 282 !(e.GetFlags() & MouseEvent::EF_IS_DOUBLE_CLICK)) { |
| 283 last_click_handler_ = NULL; |
| 284 return false; |
| 285 } |
| 286 |
275 UpdateCursor(e); | 287 UpdateCursor(e); |
276 | |
277 SetMouseLocationAndFlags(e); | 288 SetMouseLocationAndFlags(e); |
278 | 289 |
279 // If mouse_pressed_handler_ is non null, we are currently processing | 290 // If mouse_pressed_handler_ is non null, we are currently processing |
280 // a pressed -> drag -> released session. In that case we send the | 291 // a pressed -> drag -> released session. In that case we send the |
281 // event to mouse_pressed_handler_ | 292 // event to mouse_pressed_handler_ |
282 if (mouse_pressed_handler_) { | 293 if (mouse_pressed_handler_) { |
283 MouseEvent mouse_pressed_event(e, this, mouse_pressed_handler_); | 294 MouseEvent mouse_pressed_event(e, this, mouse_pressed_handler_); |
284 drag_info.Reset(); | 295 drag_info.Reset(); |
285 mouse_pressed_handler_->ProcessMousePressed(mouse_pressed_event, | 296 mouse_pressed_handler_->ProcessMousePressed(mouse_pressed_event, |
286 &drag_info); | 297 &drag_info); |
287 return true; | 298 return true; |
288 } | 299 } |
289 DCHECK(!explicit_mouse_handler_); | 300 DCHECK(!explicit_mouse_handler_); |
290 | 301 |
291 bool hit_disabled_view = false; | 302 bool hit_disabled_view = false; |
292 // Walk up the tree until we find a view that wants the mouse event. | 303 // Walk up the tree until we find a view that wants the mouse event. |
293 for (mouse_pressed_handler_ = GetViewForPoint(e.location()); | 304 for (mouse_pressed_handler_ = GetViewForPoint(e.location()); |
294 mouse_pressed_handler_ && (mouse_pressed_handler_ != this); | 305 mouse_pressed_handler_ && (mouse_pressed_handler_ != this); |
295 mouse_pressed_handler_ = mouse_pressed_handler_->GetParent()) { | 306 mouse_pressed_handler_ = mouse_pressed_handler_->GetParent()) { |
296 if (!mouse_pressed_handler_->IsEnabled()) { | 307 if (!mouse_pressed_handler_->IsEnabled()) { |
297 // Disabled views should eat events instead of propagating them upwards. | 308 // Disabled views should eat events instead of propagating them upwards. |
298 hit_disabled_view = true; | 309 hit_disabled_view = true; |
299 break; | 310 break; |
300 } | 311 } |
301 | 312 |
302 // See if this view wants to handle the mouse press. | 313 // See if this view wants to handle the mouse press. |
303 const MouseEvent mouse_pressed_event(e, this, mouse_pressed_handler_); | 314 MouseEvent mouse_pressed_event(e, this, mouse_pressed_handler_); |
| 315 |
| 316 // Remove the double-click flag if the handler is different than the |
| 317 // one which got the first click part of the double-click. |
| 318 if (mouse_pressed_handler_ != last_click_handler_) |
| 319 mouse_pressed_event.set_flags(e.GetFlags() & |
| 320 ~MouseEvent::EF_IS_DOUBLE_CLICK); |
| 321 |
304 drag_info.Reset(); | 322 drag_info.Reset(); |
305 const bool handled = | 323 bool handled = mouse_pressed_handler_->ProcessMousePressed( |
306 mouse_pressed_handler_->ProcessMousePressed(mouse_pressed_event, | 324 mouse_pressed_event, &drag_info); |
307 &drag_info); | |
308 | 325 |
309 // The view could have removed itself from the tree when handling | 326 // The view could have removed itself from the tree when handling |
310 // OnMousePressed(). In this case, the removal notification will have | 327 // OnMousePressed(). In this case, the removal notification will have |
311 // reset mouse_pressed_handler_ to NULL out from under us. Detect this | 328 // reset mouse_pressed_handler_ to NULL out from under us. Detect this |
312 // case and stop. (See comments in view.h.) | 329 // case and stop. (See comments in view.h.) |
313 // | 330 // |
314 // NOTE: Don't return true here, because we don't want the frame to | 331 // NOTE: Don't return true here, because we don't want the frame to |
315 // forward future events to us when there's no handler. | 332 // forward future events to us when there's no handler. |
316 if (!mouse_pressed_handler_) | 333 if (!mouse_pressed_handler_) |
317 break; | 334 break; |
318 | 335 |
319 // If the view handled the event, leave mouse_pressed_handler_ set and | 336 // If the view handled the event, leave mouse_pressed_handler_ set and |
320 // return true, which will cause subsequent drag/release events to get | 337 // return true, which will cause subsequent drag/release events to get |
321 // forwarded to that view. | 338 // forwarded to that view. |
322 if (handled) | 339 if (handled) { |
| 340 last_click_handler_ = mouse_pressed_handler_; |
323 return true; | 341 return true; |
| 342 } |
324 } | 343 } |
325 | 344 |
326 // Reset mouse_pressed_handler_ to indicate that no processing is occurring. | 345 // Reset mouse_pressed_handler_ to indicate that no processing is occurring. |
327 mouse_pressed_handler_ = NULL; | 346 mouse_pressed_handler_ = NULL; |
328 | 347 |
329 if (focus_on_mouse_pressed_) { | 348 if (focus_on_mouse_pressed_) { |
330 #if defined(OS_WIN) | 349 #if defined(OS_WIN) |
331 HWND hwnd = GetWidget()->GetNativeView(); | 350 HWND hwnd = GetWidget()->GetNativeView(); |
332 if (::GetFocus() != hwnd) { | 351 if (::GetFocus() != hwnd) { |
333 ::SetFocus(hwnd); | 352 ::SetFocus(hwnd); |
334 } | 353 } |
335 #else | 354 #else |
336 NOTIMPLEMENTED(); | 355 NOTIMPLEMENTED(); |
337 #endif | 356 #endif |
338 } | 357 } |
| 358 |
| 359 // In the event that a double-click is not handled after traversing the |
| 360 // entire hierarchy (even as a single-click when sent to a different view), |
| 361 // it must be marked as handled to avoid anything happening from default |
| 362 // processing if it the first click-part was handled by us. |
| 363 if (last_click_handler_ && e.GetFlags() & MouseEvent::EF_IS_DOUBLE_CLICK) |
| 364 hit_disabled_view = true; |
| 365 |
| 366 last_click_handler_ = NULL; |
339 return hit_disabled_view; | 367 return hit_disabled_view; |
340 } | 368 } |
341 | 369 |
342 bool RootView::ConvertPointToMouseHandler(const gfx::Point& l, | 370 bool RootView::ConvertPointToMouseHandler(const gfx::Point& l, |
343 gfx::Point* p) { | 371 gfx::Point* p) { |
344 // | 372 // |
345 // If the mouse_handler was set explicitly, we need to keep | 373 // If the mouse_handler was set explicitly, we need to keep |
346 // sending events even if it was reparented in a different | 374 // sending events even if it was reparented in a different |
347 // window. (a non explicit mouse handler is automatically | 375 // window. (a non explicit mouse handler is automatically |
348 // cleared when the control is removed from the hierarchy) | 376 // cleared when the control is removed from the hierarchy) |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 | 976 |
949 void RootView::SetAccessibleName(const std::wstring& name) { | 977 void RootView::SetAccessibleName(const std::wstring& name) { |
950 accessible_name_.assign(name); | 978 accessible_name_.assign(name); |
951 } | 979 } |
952 | 980 |
953 View* RootView::GetDragView() { | 981 View* RootView::GetDragView() { |
954 return drag_view_; | 982 return drag_view_; |
955 } | 983 } |
956 | 984 |
957 } // namespace views | 985 } // namespace views |
OLD | NEW |