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/root_view.h" | 5 #include "chrome/views/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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 Source<View>(child), | 258 Source<View>(child), |
259 Details<View>(parent)); | 259 Details<View>(parent)); |
260 } | 260 } |
261 } | 261 } |
262 | 262 |
263 void RootView::SetFocusOnMousePressed(bool f) { | 263 void RootView::SetFocusOnMousePressed(bool f) { |
264 focus_on_mouse_pressed_ = f; | 264 focus_on_mouse_pressed_ = f; |
265 } | 265 } |
266 | 266 |
267 bool RootView::OnMousePressed(const MouseEvent& e) { | 267 bool RootView::OnMousePressed(const MouseEvent& e) { |
| 268 static View* last_click_handler = 0; |
| 269 |
| 270 // This function is not to handle non-client messages, so we return that |
| 271 // we are not handling it quickly except for the double-click because we |
| 272 // need to absorb it when it occurs on a different view than its single |
| 273 // click part. |
| 274 if ((e.GetFlags() & MouseEvent::EF_IS_NON_CLIENT) && |
| 275 !(e.GetFlags() & MouseEvent::EF_IS_DOUBLE_CLICK)) { |
| 276 last_click_handler = 0; |
| 277 return false; |
| 278 } |
| 279 |
268 UpdateCursor(e); | 280 UpdateCursor(e); |
269 | |
270 SetMouseLocationAndFlags(e); | 281 SetMouseLocationAndFlags(e); |
271 | 282 |
272 // If mouse_pressed_handler_ is non null, we are currently processing | 283 // If mouse_pressed_handler_ is non null, we are currently processing |
273 // a pressed -> drag -> released session. In that case we send the | 284 // a pressed -> drag -> released session. In that case we send the |
274 // event to mouse_pressed_handler_ | 285 // event to mouse_pressed_handler_ |
275 if (mouse_pressed_handler_) { | 286 if (mouse_pressed_handler_) { |
276 MouseEvent mouse_pressed_event(e, this, mouse_pressed_handler_); | 287 MouseEvent mouse_pressed_event(e, this, mouse_pressed_handler_); |
277 drag_info.Reset(); | 288 drag_info.Reset(); |
278 mouse_pressed_handler_->ProcessMousePressed(mouse_pressed_event, | 289 mouse_pressed_handler_->ProcessMousePressed(mouse_pressed_event, |
279 &drag_info); | 290 &drag_info); |
280 return true; | 291 return true; |
281 } | 292 } |
282 DCHECK(!explicit_mouse_handler_); | 293 DCHECK(!explicit_mouse_handler_); |
283 | 294 |
284 bool hit_disabled_view = false; | 295 bool hit_disabled_view = false; |
285 // Walk up the tree until we find a view that wants the mouse event. | 296 // Walk up the tree until we find a view that wants the mouse event. |
286 for (mouse_pressed_handler_ = GetViewForPoint(e.location()); | 297 for (mouse_pressed_handler_ = GetViewForPoint(e.location()); |
287 mouse_pressed_handler_ && (mouse_pressed_handler_ != this); | 298 mouse_pressed_handler_ && (mouse_pressed_handler_ != this); |
288 mouse_pressed_handler_ = mouse_pressed_handler_->GetParent()) { | 299 mouse_pressed_handler_ = mouse_pressed_handler_->GetParent()) { |
289 if (!mouse_pressed_handler_->IsEnabled()) { | 300 if (!mouse_pressed_handler_->IsEnabled()) { |
290 // Disabled views should eat events instead of propagating them upwards. | 301 // Disabled views should eat events instead of propagating them upwards. |
291 hit_disabled_view = true; | 302 hit_disabled_view = true; |
292 break; | 303 break; |
293 } | 304 } |
294 | 305 |
295 // See if this view wants to handle the mouse press. | 306 // See if this view wants to handle the mouse press. |
296 const MouseEvent mouse_pressed_event(e, this, mouse_pressed_handler_); | 307 const MouseEvent mouse_pressed_event(e, this, mouse_pressed_handler_); |
297 drag_info.Reset(); | 308 drag_info.Reset(); |
298 const bool handled = | 309 const bool handled = |
| 310 (!(e.GetFlags() & MouseEvent::EF_IS_DOUBLE_CLICK) || |
| 311 (mouse_move_handler_ == last_click_handler)) && |
299 mouse_pressed_handler_->ProcessMousePressed(mouse_pressed_event, | 312 mouse_pressed_handler_->ProcessMousePressed(mouse_pressed_event, |
300 &drag_info); | 313 &drag_info); |
301 | 314 |
302 // The view could have removed itself from the tree when handling | 315 // The view could have removed itself from the tree when handling |
303 // OnMousePressed(). In this case, the removal notification will have | 316 // OnMousePressed(). In this case, the removal notification will have |
304 // reset mouse_pressed_handler_ to NULL out from under us. Detect this | 317 // reset mouse_pressed_handler_ to NULL out from under us. Detect this |
305 // case and stop. (See comments in view.h.) | 318 // case and stop. (See comments in view.h.) |
306 // | 319 // |
307 // NOTE: Don't return true here, because we don't want the frame to | 320 // NOTE: Don't return true here, because we don't want the frame to |
308 // forward future events to us when there's no handler. | 321 // forward future events to us when there's no handler. |
309 if (!mouse_pressed_handler_) | 322 if (!mouse_pressed_handler_) |
310 break; | 323 break; |
311 | 324 |
312 // If the view handled the event, leave mouse_pressed_handler_ set and | 325 // If the view handled the event, leave mouse_pressed_handler_ set and |
313 // return true, which will cause subsequent drag/release events to get | 326 // return true, which will cause subsequent drag/release events to get |
314 // forwarded to that view. | 327 // forwarded to that view. |
315 if (handled) | 328 if (handled) { |
| 329 last_click_handler = mouse_pressed_handler_; |
316 return true; | 330 return true; |
| 331 } |
317 } | 332 } |
318 | 333 |
319 // Reset mouse_pressed_handler_ to indicate that no processing is occurring. | 334 // Reset mouse_pressed_handler_ to indicate that no processing is occurring. |
320 mouse_pressed_handler_ = NULL; | 335 mouse_pressed_handler_ = NULL; |
321 | 336 |
322 if (focus_on_mouse_pressed_) { | 337 if (focus_on_mouse_pressed_) { |
323 #if defined(OS_WIN) | 338 #if defined(OS_WIN) |
324 HWND hwnd = GetWidget()->GetHWND(); | 339 HWND hwnd = GetWidget()->GetHWND(); |
325 if (::GetFocus() != hwnd) { | 340 if (::GetFocus() != hwnd) { |
326 ::SetFocus(hwnd); | 341 ::SetFocus(hwnd); |
327 } | 342 } |
328 #else | 343 #else |
329 NOTIMPLEMENTED(); | 344 NOTIMPLEMENTED(); |
330 #endif | 345 #endif |
331 } | 346 } |
| 347 |
| 348 // If we go through the whole hierarchy and we did not find the same handler |
| 349 // for the double-click as we did for the single-click, then mark it as |
| 350 // handled to eat up any double-click that ends up in a different location |
| 351 // than its single-click part. |
| 352 if (last_click_handler && e.GetFlags() & MouseEvent::EF_IS_DOUBLE_CLICK) |
| 353 hit_disabled_view = true; |
| 354 |
| 355 last_click_handler = 0; |
332 return hit_disabled_view; | 356 return hit_disabled_view; |
333 } | 357 } |
334 | 358 |
335 bool RootView::ConvertPointToMouseHandler(const gfx::Point& l, | 359 bool RootView::ConvertPointToMouseHandler(const gfx::Point& l, |
336 gfx::Point* p) { | 360 gfx::Point* p) { |
337 // | 361 // |
338 // If the mouse_handler was set explicitly, we need to keep | 362 // If the mouse_handler was set explicitly, we need to keep |
339 // sending events even if it was reparented in a different | 363 // sending events even if it was reparented in a different |
340 // window. (a non explicit mouse handler is automatically | 364 // window. (a non explicit mouse handler is automatically |
341 // cleared when the control is removed from the hierarchy) | 365 // cleared when the control is removed from the hierarchy) |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 void RootView::SetAccessibleName(const std::wstring& name) { | 973 void RootView::SetAccessibleName(const std::wstring& name) { |
950 accessible_name_.assign(name); | 974 accessible_name_.assign(name); |
951 } | 975 } |
952 | 976 |
953 View* RootView::GetDragView() { | 977 View* RootView::GetDragView() { |
954 return drag_view_; | 978 return drag_view_; |
955 } | 979 } |
956 | 980 |
957 } // namespace views | 981 } // namespace views |
958 | 982 |
OLD | NEW |