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/ui/panels/panel_manager.h" | 5 #include "chrome/browser/ui/panels/panel_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 // area. | 25 // area. |
26 const double kPanelMaxWidthFactor = 1.0; | 26 const double kPanelMaxWidthFactor = 1.0; |
27 const double kPanelMaxHeightFactor = 0.5; | 27 const double kPanelMaxHeightFactor = 0.5; |
28 | 28 |
29 // Occasionally some system, like Windows, might not bring up or down the bottom | 29 // Occasionally some system, like Windows, might not bring up or down the bottom |
30 // bar when the mouse enters or leaves the bottom screen area. This is the | 30 // bar when the mouse enters or leaves the bottom screen area. This is the |
31 // maximum time we will wait for the bottom bar visibility change notification. | 31 // maximum time we will wait for the bottom bar visibility change notification. |
32 // After the time expires, we bring up/down the titlebars as planned. | 32 // After the time expires, we bring up/down the titlebars as planned. |
33 const int kMaxMillisecondsWaitForBottomBarVisibilityChange = 1000; | 33 const int kMaxMillisecondsWaitForBottomBarVisibilityChange = 1000; |
34 | 34 |
| 35 // See usage below. |
| 36 #if defined(OS_MACOSX) |
| 37 const int kMillisecondsBeforeCollapsingFromTitleOnlyState = 3000; |
| 38 #else |
| 39 const int kMillisecondsBeforeCollapsingFromTitleOnlyState = 0; |
| 40 #endif |
| 41 |
35 // Single instance of PanelManager. | 42 // Single instance of PanelManager. |
36 scoped_refptr<PanelManager> panel_manager_instance; | 43 scoped_ptr<PanelManager> panel_manager_instance; |
37 } // namespace | 44 } // namespace |
38 | 45 |
39 // static | 46 // static |
40 PanelManager* PanelManager::GetInstance() { | 47 PanelManager* PanelManager::GetInstance() { |
41 if (!panel_manager_instance.get()) | 48 if (!panel_manager_instance.get()) |
42 panel_manager_instance = new PanelManager(); | 49 panel_manager_instance.reset(new PanelManager()); |
43 return panel_manager_instance.get(); | 50 return panel_manager_instance.get(); |
44 } | 51 } |
45 | 52 |
46 PanelManager::PanelManager() | 53 PanelManager::PanelManager() |
47 : minimized_panel_count_(0), | 54 : minimized_panel_count_(0), |
48 are_titlebars_up_(false), | 55 are_titlebars_up_(false), |
49 dragging_panel_index_(kInvalidPanelIndex), | 56 dragging_panel_index_(kInvalidPanelIndex), |
50 dragging_panel_original_x_(0), | 57 dragging_panel_original_x_(0), |
51 delayed_titlebar_action_(NO_ACTION), | 58 delayed_titlebar_action_(NO_ACTION), |
52 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 59 remove_delays_for_testing_(false), |
| 60 titlebar_action_task_(NULL), |
53 auto_sizing_enabled_(true), | 61 auto_sizing_enabled_(true), |
54 mouse_watching_disabled_(false) { | 62 mouse_watching_disabled_(false) { |
55 panel_mouse_watcher_.reset(PanelMouseWatcher::Create(this)); | 63 panel_mouse_watcher_.reset(PanelMouseWatcher::Create(this)); |
56 auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this); | 64 auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this); |
57 OnDisplayChanged(); | 65 OnDisplayChanged(); |
58 } | 66 } |
59 | 67 |
60 PanelManager::~PanelManager() { | 68 PanelManager::~PanelManager() { |
61 DCHECK(panels_.empty()); | 69 DCHECK(panels_.empty()); |
62 DCHECK(panels_pending_to_remove_.empty()); | 70 DCHECK(panels_pending_to_remove_.empty()); |
63 DCHECK_EQ(0, minimized_panel_count_); | 71 DCHECK_EQ(0, minimized_panel_count_); |
| 72 if (titlebar_action_task_) { |
| 73 titlebar_action_task_->Cancel(); |
| 74 titlebar_action_task_ = NULL; |
| 75 } |
64 } | 76 } |
65 | 77 |
66 void PanelManager::OnDisplayChanged() { | 78 void PanelManager::OnDisplayChanged() { |
67 scoped_ptr<WindowSizer::MonitorInfoProvider> info_provider( | 79 scoped_ptr<WindowSizer::MonitorInfoProvider> info_provider( |
68 WindowSizer::CreateDefaultMonitorInfoProvider()); | 80 WindowSizer::CreateDefaultMonitorInfoProvider()); |
69 SetWorkArea(info_provider->GetPrimaryMonitorWorkArea()); | 81 SetWorkArea(info_provider->GetPrimaryMonitorWorkArea()); |
70 } | 82 } |
71 | 83 |
72 void PanelManager::SetWorkArea(const gfx::Rect& work_area) { | 84 void PanelManager::SetWorkArea(const gfx::Rect& work_area) { |
73 if (work_area == work_area_) | 85 if (work_area == work_area_) |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 | 397 |
386 for (Panels::const_iterator iter = panels_.begin(); | 398 for (Panels::const_iterator iter = panels_.begin(); |
387 iter != panels_.end(); ++iter) { | 399 iter != panels_.end(); ++iter) { |
388 if ((*iter)->ShouldBringUpTitlebar(mouse_x, mouse_y)) | 400 if ((*iter)->ShouldBringUpTitlebar(mouse_x, mouse_y)) |
389 return true; | 401 return true; |
390 } | 402 } |
391 return false; | 403 return false; |
392 } | 404 } |
393 | 405 |
394 void PanelManager::BringUpOrDownTitlebars(bool bring_up) { | 406 void PanelManager::BringUpOrDownTitlebars(bool bring_up) { |
| 407 int task_delay_milliseconds = 0; |
| 408 |
395 // If the auto-hiding bottom bar exists, delay the action until the bottom | 409 // If the auto-hiding bottom bar exists, delay the action until the bottom |
396 // bar is fully visible or hidden. We do not want both bottom bar and panel | 410 // bar is fully visible or hidden. We do not want both bottom bar and panel |
397 // titlebar to move at the same time but with different speeds. | 411 // titlebar to move at the same time but with different speeds. |
398 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { | 412 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { |
399 AutoHidingDesktopBar::Visibility visibility = auto_hiding_desktop_bar_-> | 413 AutoHidingDesktopBar::Visibility visibility = auto_hiding_desktop_bar_-> |
400 GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM); | 414 GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM); |
401 if (visibility != (bring_up ? AutoHidingDesktopBar::VISIBLE | 415 if (visibility != (bring_up ? AutoHidingDesktopBar::VISIBLE |
402 : AutoHidingDesktopBar::HIDDEN)) { | 416 : AutoHidingDesktopBar::HIDDEN)) { |
403 // OnAutoHidingDesktopBarVisibilityChanged will handle this. | |
404 delayed_titlebar_action_ = bring_up ? BRING_UP : BRING_DOWN; | |
405 | |
406 // Occasionally some system, like Windows, might not bring up or down the | 417 // Occasionally some system, like Windows, might not bring up or down the |
407 // bottom bar when the mouse enters or leaves the bottom screen area. | 418 // bottom bar when the mouse enters or leaves the bottom screen area. |
408 // Thus, we schedule a delayed task to do the work if we do not receive | 419 // Thus, we schedule a delayed task to do the work if we do not receive |
409 // the bottom bar visibility change notification within a certain period | 420 // the bottom bar visibility change notification within a certain period |
410 // of time. | 421 // of time. |
411 MessageLoop::current()->PostDelayedTask( | 422 task_delay_milliseconds = |
412 FROM_HERE, | 423 kMaxMillisecondsWaitForBottomBarVisibilityChange; |
413 method_factory_.NewRunnableMethod( | |
414 &PanelManager::DelayedBringUpOrDownTitlebarsCheck), | |
415 kMaxMillisecondsWaitForBottomBarVisibilityChange); | |
416 | |
417 return; | |
418 } | 424 } |
419 } | 425 } |
420 | 426 |
421 DoBringUpOrDownTitlebars(bring_up); | 427 // On some OSes, the interaction with native Taskbars/Docks may be improved |
| 428 // if the panels do not go back to minimized state too fast. For example, |
| 429 // it makes it possible to hit the titlebar on OSX if Dock has Magnifying |
| 430 // enabled - the panels stay up for a while after Dock magnification effect |
| 431 // stops covering the panels. |
| 432 // TODO(dimich): when there is implementation which has both delays to be |
| 433 // different from zero, figure out what shoudl be the combined delay. |
| 434 if (!bring_up && |
| 435 task_delay_milliseconds < kMillisecondsBeforeCollapsingFromTitleOnlyState) |
| 436 task_delay_milliseconds = kMillisecondsBeforeCollapsingFromTitleOnlyState; |
| 437 |
| 438 // OnAutoHidingDesktopBarVisibilityChanged will handle this. |
| 439 delayed_titlebar_action_ = bring_up ? BRING_UP : BRING_DOWN; |
| 440 if (remove_delays_for_testing_) |
| 441 task_delay_milliseconds = 0; |
| 442 |
| 443 // If user moves the mouse in and out of mouse tracking area, we might have |
| 444 // previously posted but not yet dispatched task in the queue. New action |
| 445 // shoudl always 'reset' the delays so cancel the old task and post a new one. |
| 446 if (titlebar_action_task_) |
| 447 titlebar_action_task_->Cancel(); |
| 448 |
| 449 titlebar_action_task_ = NewRunnableMethod( |
| 450 this, &PanelManager::DelayedBringUpOrDownTitlebarsCheck); |
| 451 |
| 452 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 453 titlebar_action_task_, |
| 454 task_delay_milliseconds); |
422 } | 455 } |
423 | 456 |
424 void PanelManager::DelayedBringUpOrDownTitlebarsCheck() { | 457 void PanelManager::DelayedBringUpOrDownTitlebarsCheck() { |
| 458 titlebar_action_task_ = NULL; |
| 459 |
| 460 // Task was already processed or cancelled - bail out. |
425 if (delayed_titlebar_action_ == NO_ACTION) | 461 if (delayed_titlebar_action_ == NO_ACTION) |
426 return; | 462 return; |
427 | 463 |
428 DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP); | 464 bool need_to_bring_up_titlebars = (delayed_titlebar_action_ == BRING_UP); |
| 465 |
429 delayed_titlebar_action_ = NO_ACTION; | 466 delayed_titlebar_action_ = NO_ACTION; |
| 467 |
| 468 // Check if the action is still needed based on the latest mouse position. The |
| 469 // user could move the mouse into the tracking area and then quickly move it |
| 470 // out of the area. In case of this, cancel the action. |
| 471 if (are_titlebars_up_ != need_to_bring_up_titlebars) |
| 472 return; |
| 473 |
| 474 DoBringUpOrDownTitlebars(need_to_bring_up_titlebars); |
430 } | 475 } |
431 | 476 |
432 void PanelManager::DoBringUpOrDownTitlebars(bool bring_up) { | 477 void PanelManager::DoBringUpOrDownTitlebars(bool bring_up) { |
433 for (Panels::const_iterator iter = panels_.begin(); | 478 for (Panels::const_iterator iter = panels_.begin(); |
434 iter != panels_.end(); ++iter) { | 479 iter != panels_.end(); ++iter) { |
435 Panel* panel = *iter; | 480 Panel* panel = *iter; |
436 | 481 |
437 // Skip any panel that is drawing the attention. | 482 // Skip any panel that is drawing the attention. |
438 if (panel->IsDrawingAttention()) | 483 if (panel->IsDrawingAttention()) |
439 continue; | 484 continue; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 // Start from the bottom to avoid reshuffling. | 597 // Start from the bottom to avoid reshuffling. |
553 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 598 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
554 iter != panels_copy.rend(); ++iter) | 599 iter != panels_copy.rend(); ++iter) |
555 (*iter)->Close(); | 600 (*iter)->Close(); |
556 } | 601 } |
557 | 602 |
558 bool PanelManager::is_dragging_panel() const { | 603 bool PanelManager::is_dragging_panel() const { |
559 return dragging_panel_index_ != kInvalidPanelIndex; | 604 return dragging_panel_index_ != kInvalidPanelIndex; |
560 } | 605 } |
561 | 606 |
OLD | NEW |