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

Unified Diff: chrome/browser/ui/panels/panel_manager.cc

Issue 7646003: Support auto-hide taskbar for panels on Windows. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/panels/panel_manager.h ('k') | chrome/browser/ui/panels/panel_mouse_watcher_win.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/panels/panel_manager.cc
===================================================================
--- chrome/browser/ui/panels/panel_manager.cc (revision 98834)
+++ chrome/browser/ui/panels/panel_manager.cc (working copy)
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/window_sizer.h"
@@ -28,26 +29,29 @@
const double kPanelMaxWidthFactor = 1.0;
const double kPanelMaxHeightFactor = 0.5;
+// Occasionally some system, like Windows, might not bring up or down the bottom
+// bar when the mouse enters or leaves the bottom screen area. This is the
+// maximum time we will wait for the bottom bar visibility change notification.
+// After the time expires, we bring up/down the titlebars as planned.
+const int kMaxMillisecondsWaitForBottomBarVisibilityChange = 1000;
+
// Single instance of PanelManager.
-scoped_ptr<PanelManager> panel_instance;
+scoped_refptr<PanelManager> panel_instance;
} // namespace
// static
PanelManager* PanelManager::GetInstance() {
- if (!panel_instance.get()) {
- panel_instance.reset(new PanelManager());
- }
+ if (!panel_instance.get())
+ panel_instance = new PanelManager();
return panel_instance.get();
}
PanelManager::PanelManager()
- : max_width_(0),
- max_height_(0),
- min_x_(0),
- current_x_(0),
- bottom_edge_y_(0),
- dragging_panel_index_(kInvalidPanelIndex),
- dragging_panel_original_x_(0) {
+ : dragging_panel_index_(kInvalidPanelIndex),
+ dragging_panel_original_x_(0),
+ delayed_titlebar_action_(NO_ACTION),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
+ auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this);
OnDisplayChanged();
}
@@ -67,13 +71,10 @@
return;
work_area_ = work_area;
- min_x_ = work_area.x();
- current_x_ = work_area.right();
- bottom_edge_y_ = work_area.bottom();
- max_width_ = static_cast<int>(work_area.width() * kPanelMaxWidthFactor);
- max_height_ = static_cast<int>(work_area.height() * kPanelMaxHeightFactor);
+ auto_hiding_desktop_bar_->UpdateWorkArea(work_area_);
+ AdjustWorkAreaForAutoHidingDesktopBars();
- Rearrange(panels_.begin());
+ Rearrange(panels_.begin(), adjusted_work_area_.right());
}
void PanelManager::FindAndClosePanelOnOverflow(const Extension* extension) {
@@ -97,20 +98,55 @@
}
Panel* PanelManager::CreatePanel(Browser* browser) {
+ // Adjust the width and height to fit into our constraint.
+ int width = browser->override_bounds().width();
+ int height = browser->override_bounds().height();
+
+ if (width == 0 && height == 0) {
+ width = kPanelDefaultWidthPixels;
+ height = kPanelDefaultHeightPixels;
+ }
+
+ int max_panel_width =
+ static_cast<int>(adjusted_work_area_.width() * kPanelMaxWidthFactor);
+ int max_panel_height =
+ static_cast<int>(adjusted_work_area_.height() * kPanelMaxHeightFactor);
+
+ if (width < kPanelMinWidthPixels)
+ width = kPanelMinWidthPixels;
+ else if (width > max_panel_width)
+ width = max_panel_width;
+
+ if (height < kPanelMinHeightPixels)
+ height = kPanelMinHeightPixels;
+ else if (height > max_panel_height)
+ height = max_panel_height;
+
+ // Compute the origin. Ensure that it falls within the adjusted work area by
+ // closing other panels if needed.
+ int y = adjusted_work_area_.bottom() - height;
+
const Extension* extension = NULL;
- gfx::Rect bounds = browser->override_bounds();
- while (!ComputeBoundsForNextPanel(&bounds, true)) {
+ int x;
+ while ((x = GetRightMostAvaialblePosition() - width) <
+ adjusted_work_area_.x() ) {
if (!extension)
extension = Panel::GetExtension(browser);
FindAndClosePanelOnOverflow(extension);
}
- Panel* panel = new Panel(browser, bounds);
+ // Now create the panel with the computed bounds.
+ Panel* panel = new Panel(browser, gfx::Rect(x, y, width, height));
panels_.push_back(panel);
return panel;
}
+int PanelManager::GetRightMostAvaialblePosition() const {
+ return panels_.empty() ? adjusted_work_area_.right() :
+ (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing);
+}
+
void PanelManager::Remove(Panel* panel) {
// If we're in the process of dragging, delay the removal.
if (dragging_panel_index_ != kInvalidPanelIndex) {
@@ -133,8 +169,7 @@
return;
gfx::Rect bounds = (*iter)->GetBounds();
- current_x_ = bounds.x() + bounds.width();
- Rearrange(panels_.erase(iter));
+ Rearrange(panels_.erase(iter), bounds.right());
}
void PanelManager::StartDragging(Panel* panel) {
@@ -268,8 +303,16 @@
DelayedRemove();
}
-bool PanelManager::ShouldBringUpTitlebarForAllMinimizedPanels(
- int mouse_x, int mouse_y) const {
+bool PanelManager::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const {
+ // We should always bring up the titlebar if the mouse is over the
+ // visible auto-hiding bottom bar.
+ if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) &&
+ auto_hiding_desktop_bar_->GetVisibility(
+ AutoHidingDesktopBar::ALIGN_BOTTOM) ==
+ AutoHidingDesktopBar::VISIBLE &&
+ mouse_y >= adjusted_work_area_.bottom())
+ return true;
+
for (Panels::const_iterator iter = panels_.begin();
iter != panels_.end(); ++iter) {
if ((*iter)->ShouldBringUpTitlebar(mouse_x, mouse_y))
@@ -278,7 +321,45 @@
return false;
}
-void PanelManager::BringUpOrDownTitlebarForAllMinimizedPanels(bool bring_up) {
+void PanelManager::BringUpOrDownTitlebars(bool bring_up) {
+ // If the auto-hiding bottom bar exists, delay the action until the bottom
+ // bar is fully visible or hidden. We do not want both bottom bar and panel
+ // titlebar to move at the same time but with different speeds.
+ if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) {
+ AutoHidingDesktopBar::Visibility visibility = auto_hiding_desktop_bar_->
+ GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM);
+ if (visibility != (bring_up ? AutoHidingDesktopBar::VISIBLE
+ : AutoHidingDesktopBar::HIDDEN)) {
+ // OnAutoHidingDesktopBarVisibilityChanged will handle this.
+ delayed_titlebar_action_ = bring_up ? BRING_UP : BRING_DOWN;
+
+ // Occasionally some system, like Windows, might not bring up or down the
+ // bottom bar when the mouse enters or leaves the bottom screen area.
+ // Thus, we schedule a delayed task to do the work if we do not receive
+ // the bottom bar visibility change notification within a certain period
+ // of time.
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &PanelManager::DelayedBringUpOrDownTitlebarsCheck),
+ kMaxMillisecondsWaitForBottomBarVisibilityChange);
+
+ return;
+ }
+ }
+
+ DoBringUpOrDownTitlebars(bring_up);
+}
+
+void PanelManager::DelayedBringUpOrDownTitlebarsCheck() {
+ if (delayed_titlebar_action_ == NO_ACTION)
+ return;
+
+ DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP);
+ delayed_titlebar_action_ = NO_ACTION;
+}
+
+void PanelManager::DoBringUpOrDownTitlebars(bool bring_up) {
for (Panels::const_iterator iter = panels_.begin();
iter != panels_.end(); ++iter) {
Panel* panel = *iter;
@@ -297,51 +378,78 @@
}
}
-void PanelManager::Rearrange(Panels::iterator iter_to_start) {
- if (iter_to_start == panels_.end())
- return;
+void PanelManager::AdjustWorkAreaForAutoHidingDesktopBars() {
+ // Note that we do not care about the desktop bar aligned to the top edge
+ // since panels could not reach so high due to size constraint.
+ adjusted_work_area_ = work_area_;
+ if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) {
+ int space = auto_hiding_desktop_bar_->GetThickness(
+ AutoHidingDesktopBar::ALIGN_BOTTOM);
+ adjusted_work_area_.set_height(adjusted_work_area_.height() - space);
+ }
+ if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_LEFT)) {
+ int space = auto_hiding_desktop_bar_->GetThickness(
+ AutoHidingDesktopBar::ALIGN_LEFT);
+ adjusted_work_area_.set_x(adjusted_work_area_.x() + space);
+ adjusted_work_area_.set_width(adjusted_work_area_.width() - space);
+ }
+ if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_RIGHT)) {
+ int space = auto_hiding_desktop_bar_->GetThickness(
+ AutoHidingDesktopBar::ALIGN_RIGHT);
+ adjusted_work_area_.set_width(adjusted_work_area_.width() - space);
+ }
+}
- for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) {
- gfx::Rect new_bounds((*iter)->GetBounds());
- ComputeBoundsForNextPanel(&new_bounds, false);
- if (new_bounds != (*iter)->GetBounds())
- (*iter)->SetPanelBounds(new_bounds);
+int PanelManager::GetBottomPositionForExpansionState(
+ Panel::ExpansionState expansion_state) const {
+ // If there is an auto-hiding desktop bar aligned to the bottom edge, we need
+ // to move the minimize panel down to the bottom edge.
+ int bottom = adjusted_work_area_.bottom();
+ if (expansion_state == Panel::MINIMIZED &&
+ auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) {
+ bottom += auto_hiding_desktop_bar_->GetThickness(
+ AutoHidingDesktopBar::ALIGN_BOTTOM);
}
+ return bottom;
}
-bool PanelManager::ComputeBoundsForNextPanel(gfx::Rect* bounds,
- bool allow_size_change) {
- int width = bounds->width();
- int height = bounds->height();
+void PanelManager::OnAutoHidingDesktopBarThicknessChanged() {
+ AdjustWorkAreaForAutoHidingDesktopBars();
+ Rearrange(panels_.begin(), adjusted_work_area_.right());
+}
- // Update the width and/or height to fit into our constraint.
- if (allow_size_change) {
- if (width == 0 && height == 0) {
- width = kPanelDefaultWidthPixels;
- height = kPanelDefaultHeightPixels;
- }
+void PanelManager::OnAutoHidingDesktopBarVisibilityChanged(
+ AutoHidingDesktopBar::Alignment alignment,
+ AutoHidingDesktopBar::Visibility visibility) {
+ if (delayed_titlebar_action_ == NO_ACTION)
+ return;
- if (width < kPanelMinWidthPixels)
- width = kPanelMinWidthPixels;
- else if (width > max_width_)
- width = max_width_;
+ AutoHidingDesktopBar::Visibility expected_visibility =
+ delayed_titlebar_action_ == BRING_UP ? AutoHidingDesktopBar::VISIBLE
+ : AutoHidingDesktopBar::HIDDEN;
+ if (visibility != expected_visibility)
+ return;
- if (height < kPanelMinHeightPixels)
- height = kPanelMinHeightPixels;
- else if (height > max_height_)
- height = max_height_;
- }
+ DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP);
+ delayed_titlebar_action_ = NO_ACTION;
+}
- int x = current_x_ - width;
- int y = bottom_edge_y_ - height;
+void PanelManager::Rearrange(Panels::iterator iter_to_start,
+ int rightmost_position) {
+ if (iter_to_start == panels_.end())
+ return;
- if (x < min_x_)
- return false;
+ for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) {
+ Panel* panel = *iter;
- current_x_ -= width + kPanelsHorizontalSpacing;
+ gfx::Rect new_bounds(panel->GetBounds());
+ new_bounds.set_x(rightmost_position - new_bounds.width());
+ new_bounds.set_y(adjusted_work_area_.bottom() - new_bounds.height());
+ if (new_bounds != panel->GetBounds())
+ panel->SetPanelBounds(new_bounds);
- bounds->SetRect(x, y, width, height);
- return true;
+ rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing;
+ }
}
void PanelManager::RemoveAll() {
« no previous file with comments | « chrome/browser/ui/panels/panel_manager.h ('k') | chrome/browser/ui/panels/panel_mouse_watcher_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698