Chromium Code Reviews| Index: chrome/browser/ui/window_sizer/window_sizer_ash.cc |
| diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash.cc b/chrome/browser/ui/window_sizer/window_sizer_ash.cc |
| index fc07742570e11f10fbfdac1564a03df0ae374f67..7e5f04ef0bc0f8fee2faf64c47eb0e613230a659 100644 |
| --- a/chrome/browser/ui/window_sizer/window_sizer_ash.cc |
| +++ b/chrome/browser/ui/window_sizer/window_sizer_ash.cc |
| @@ -18,28 +18,41 @@ |
| namespace { |
| -// Check if the window was not created as popup or as panel. |
| -bool IsValidToplevelWindow(aura::Window* window) { |
| +// Check if the given browser is 'valid': It is a tabbed, non minimized |
| +// window, which intersects with the |bounds| area of a given screen. |
| +bool IsValidBrowser(Browser* browser, const gfx::Rect& bounds) { |
| + return (browser && browser->window() && |
| + !(browser->is_type_popup() || browser->is_type_panel()) && |
| + !browser->window()->IsMinimized() && |
| + browser->window()->GetNativeWindow() && |
| + bounds.Intersects( |
| + browser->window()->GetNativeWindow()->GetBoundsInScreen())); |
| + |
|
sky
2012/09/13 17:32:02
remove this newline.
Mr4D (OOO till 08-26)
2012/09/13 18:56:59
Done.
|
| +} |
| + |
| +// Check if the window was not created as popup or as panel, it is |
| +// on the screen defined by |bounds| and visible. |
| +bool IsValidToplevelWindow(aura::Window* window, const gfx::Rect& bounds) { |
| for (BrowserList::const_iterator iter = BrowserList::begin(); |
| iter != BrowserList::end(); |
| ++iter) { |
| Browser* browser = *iter; |
| if (browser && browser->window() && |
| - browser->window()->GetNativeWindow() == window) { |
| - return (!(browser->is_type_popup() || browser->is_type_panel())); |
| - } |
| + browser->window()->GetNativeWindow() == window) |
| + return IsValidBrowser(browser, bounds); |
| } |
| // A window which has no browser associated with it is probably not a window |
| // of which we want to copy the size from. |
| return false; |
| } |
| -// Get the first open window in the stack on the screen. |
| -aura::Window* GetTopWindow() { |
| +// Get the first open (non minimized) window which is on the screen defined |
| +// by |bounds| and visible. |
| +aura::Window* GetTopWindow(const gfx::Rect& bounds) { |
| // Get the active window. |
| aura::Window* window = ash::wm::GetActiveWindow(); |
| if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && |
| - window->IsVisible() && IsValidToplevelWindow(window)) |
| + window->IsVisible() && IsValidToplevelWindow(window, bounds)) |
| return window; |
| // Get a list of all windows. |
| @@ -63,34 +76,84 @@ aura::Window* GetTopWindow() { |
| for (int i = index + windows.size(); i >= 0; i--) { |
| aura::Window* window = windows[i % windows.size()]; |
| if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && |
| - window->IsVisible() && IsValidToplevelWindow(window)) |
| + bounds.Intersects(window->GetBoundsInScreen()) && |
| + window->IsVisible() && IsValidToplevelWindow(window, bounds)) |
| return window; |
| } |
| return NULL; |
| } |
| +// Return the number of valid top level windows on the screen defined by |
| +// the |bounds| rectangle. |
| +int GetNumberOfValidTopLevelBrowserWindows(const gfx::Rect& bounds) { |
| + int count = 0; |
| + for (BrowserList::const_iterator iter = BrowserList::begin(); |
| + iter != BrowserList::end(); |
| + ++iter) { |
| + if (IsValidBrowser(*iter, bounds)) |
| + count++; |
| + } |
| + return count; |
| +} |
| + |
| +// Move the given |bounds| on the available |work_area| to the direction. |
| +// If |move_right| is true, the rectangle gets moved to the right corner. |
| +// otherwise to the left side. |
| +bool MoveRect(const gfx::Rect& work_area, gfx::Rect& bounds, bool move_right) { |
| + if (move_right) { |
| + if (work_area.right() > bounds.right()) { |
| + bounds.set_x(work_area.right() - bounds.width()); |
| + return true; |
| + } |
| + } else { |
| + if (work_area.x() < bounds.x()) { |
| + bounds.set_x(work_area.x()); |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| } // namespace |
| -bool WindowSizer::GetBoundsIgnoringPreviousStateAsh( |
| - const gfx::Rect& specified_bounds, |
| - gfx::Rect* bounds) const { |
| +bool WindowSizer::GetBoundsOverrideAsh(const gfx::Rect& specified_bounds, |
| + gfx::Rect* bounds) const { |
| *bounds = specified_bounds; |
| DCHECK(bounds->IsEmpty()); |
| + |
| + if (!GetSavedWindowBounds(bounds)) |
| + GetDefaultWindowBounds(bounds); |
| + |
| if (browser_ != NULL && browser_->type() == Browser::TYPE_TABBED) { |
| + gfx::Rect work_area = |
| + monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds); |
| // This is a window / app. See if there is no window and try to place it. |
| - aura::Window* top_window = GetTopWindow(); |
| - // If there are no windows we have a special case and try to |
| - // maximize which leaves a 'border' which shows the desktop. |
| - if (top_window == NULL) { |
| - GetDefaultWindowBounds(bounds); |
| - } else { |
| - *bounds = top_window->GetBoundsInScreen(); |
| - gfx::Rect work_area = |
| - monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds); |
| - *bounds = bounds->AdjustToFit(work_area); |
| + int count = GetNumberOfValidTopLevelBrowserWindows(work_area); |
| + aura::Window* top_window = GetTopWindow(work_area); |
| + |
| + // If there is no valid other window we take the coordinates as is. |
| + if (!count || !top_window || ash::wm::IsWindowMaximized(top_window)) |
| + return true; |
| + |
| + gfx::Rect other_bounds = top_window->bounds(); |
| + bool move_right = |
| + other_bounds.CenterPoint().x() < work_area.CenterPoint().x(); |
| + |
| + // In case we have only one window, we move the other window fully to the |
| + // "other side" - making room for this new window. |
| + if (count == 1) { |
| + if (MoveRect(work_area, other_bounds, !move_right)) |
|
sky
2012/09/13 17:32:02
You're comparing screen bounds and non-screen boun
Mr4D (OOO till 08-26)
2012/09/13 18:56:59
Thanks for your explanations of the term 'screen'
|
| + top_window->SetBounds(other_bounds); |
|
sky
2012/09/13 17:32:02
Moving a window makes me nervous. Consider the cas
Mr4D (OOO till 08-26)
2012/09/13 18:56:59
Well - this automatic movement was requested by Al
|
| } |
| + // Use the size of the other window, and mirror the location to the |
| + // opposite side. Then make sure that it is inside our work area |
| + // (if possible). |
| + *bounds = other_bounds; |
| + MoveRect(work_area, *bounds, move_right); |
| + if (bounds->bottom() > work_area.bottom()) |
| + bounds->set_y(std::max(work_area.y(), |
| + work_area.bottom() - bounds->height())); |
| return true; |
| - // If both fail we will continue the default path. |
| } |
| return false; |