| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/window_sizer.h" | |
| 6 | |
| 7 #include "ash/shell.h" | |
| 8 #include "ash/wm/window_cycle_controller.h" | |
| 9 #include "ash/wm/window_util.h" | |
| 10 #include "base/compiler_specific.h" | |
| 11 #include "chrome/browser/browser_process.h" | |
| 12 #include "chrome/browser/ui/browser.h" | |
| 13 #include "chrome/browser/ui/browser_list.h" | |
| 14 #include "chrome/browser/ui/browser_window.h" | |
| 15 #include "ui/aura/window.h" | |
| 16 #include "ui/aura/window_delegate.h" | |
| 17 #include "ui/gfx/screen.h" | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 // Check if the window was not created as popup or as panel. | |
| 22 bool IsValidToplevelWindow(aura::Window* window) { | |
| 23 for (BrowserList::const_iterator iter = BrowserList::begin(); | |
| 24 iter != BrowserList::end(); | |
| 25 ++iter) { | |
| 26 Browser* browser = *iter; | |
| 27 if (browser && browser->window() && | |
| 28 browser->window()->GetNativeWindow() == window) { | |
| 29 return (!(browser->is_type_popup() || browser->is_type_panel())); | |
| 30 } | |
| 31 } | |
| 32 // A window which has no browser associated with it is probably not a window | |
| 33 // of which we want to copy the size from. | |
| 34 return false; | |
| 35 } | |
| 36 | |
| 37 // Get the first open window in the stack on the screen. | |
| 38 aura::Window* GetTopWindow() { | |
| 39 // Get the active window. | |
| 40 aura::Window* window = ash::wm::GetActiveWindow(); | |
| 41 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && | |
| 42 window->IsVisible() && IsValidToplevelWindow(window)) | |
| 43 return window; | |
| 44 | |
| 45 // Get a list of all windows. | |
| 46 const std::vector<aura::Window*> windows = | |
| 47 ash::WindowCycleController::BuildWindowList(); | |
| 48 | |
| 49 if (windows.empty()) | |
| 50 return NULL; | |
| 51 | |
| 52 aura::Window::Windows::const_iterator iter = windows.begin(); | |
| 53 // Find the index of the current window. | |
| 54 if (window) | |
| 55 iter = std::find(windows.begin(), windows.end(), window); | |
| 56 | |
| 57 int index = (iter == windows.end()) ? 0 : (iter - windows.begin()); | |
| 58 | |
| 59 // Scan the cycle list backwards to see which is the second topmost window | |
| 60 // (and so on). Note that we might cycle a few indices twice if there is no | |
| 61 // suitable window. However - since the list is fairly small this should be | |
| 62 // very fast anyways. | |
| 63 for (int i = index + windows.size(); i >= 0; i--) { | |
| 64 aura::Window* window = windows[i % windows.size()]; | |
| 65 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && | |
| 66 window->IsVisible() && IsValidToplevelWindow(window)) | |
| 67 return window; | |
| 68 } | |
| 69 return NULL; | |
| 70 } | |
| 71 | |
| 72 } // namespace | |
| 73 | |
| 74 bool WindowSizer::GetBoundsIgnoringPreviousStateAsh( | |
| 75 const gfx::Rect& specified_bounds, | |
| 76 gfx::Rect* bounds) const { | |
| 77 *bounds = specified_bounds; | |
| 78 DCHECK(bounds->IsEmpty()); | |
| 79 if (browser_ != NULL && browser_->type() == Browser::TYPE_TABBED) { | |
| 80 // This is a window / app. See if there is no window and try to place it. | |
| 81 aura::Window* top_window = GetTopWindow(); | |
| 82 // If there are no windows we have a special case and try to | |
| 83 // maximize which leaves a 'border' which shows the desktop. | |
| 84 if (top_window == NULL) { | |
| 85 GetDefaultWindowBounds(bounds); | |
| 86 } else { | |
| 87 *bounds = top_window->GetBoundsInRootWindow(); | |
| 88 gfx::Rect work_area = | |
| 89 monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds); | |
| 90 *bounds = bounds->AdjustToFit(work_area); | |
| 91 } | |
| 92 return true; | |
| 93 // If both fail we will continue the default path. | |
| 94 } | |
| 95 | |
| 96 return false; | |
| 97 } | |
| 98 | |
| 99 void WindowSizer::GetDefaultWindowBoundsAsh(gfx::Rect* default_bounds) const { | |
| 100 DCHECK(default_bounds); | |
| 101 DCHECK(monitor_info_provider_.get()); | |
| 102 | |
| 103 gfx::Rect work_area = monitor_info_provider_->GetPrimaryDisplayWorkArea(); | |
| 104 | |
| 105 DCHECK_EQ(kDesktopBorderSize, ash::Shell::GetInstance()->GetGridSize()); | |
| 106 | |
| 107 // There should be a 'desktop' border around the window at the left and right | |
| 108 // side. | |
| 109 int default_width = work_area.width() - 2 * kDesktopBorderSize; | |
| 110 // There should also be a 'desktop' border around the window at the top. | |
| 111 // Since the workspace excludes the tray area we only need one border size. | |
| 112 int default_height = work_area.height() - kDesktopBorderSize; | |
| 113 // We align the size to the grid size to avoid any surprise when the | |
| 114 // monitor height isn't divide-able by our alignment factor. | |
| 115 default_width -= default_width % kDesktopBorderSize; | |
| 116 default_height -= default_height % kDesktopBorderSize; | |
| 117 int offset_x = kDesktopBorderSize; | |
| 118 int maximum_window_width = 1280; | |
| 119 if (default_width > maximum_window_width) { | |
| 120 // The window should get centered on the screen and not follow the grid. | |
| 121 offset_x = (work_area.width() - maximum_window_width) / 2; | |
| 122 // Never make a window wider then 1280. | |
| 123 default_width = maximum_window_width; | |
| 124 } | |
| 125 default_bounds->SetRect(work_area.x() + offset_x, | |
| 126 work_area.y() + kDesktopBorderSize, | |
| 127 default_width, | |
| 128 default_height); | |
| 129 } | |
| OLD | NEW |