OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ash/wm/workspace/workspace_layout_manager.h" | 5 #include "ash/wm/workspace/workspace_layout_manager.h" |
6 | 6 |
7 #include "ash/root_window_controller.h" | 7 #include "ash/root_window_controller.h" |
8 #include "ash/screen_ash.h" | 8 #include "ash/screen_ash.h" |
9 #include "ash/shelf/shelf_layout_manager.h" | 9 #include "ash/shelf/shelf_layout_manager.h" |
10 #include "ash/shell.h" | 10 #include "ash/shell.h" |
(...skipping 14 matching lines...) Expand all Loading... | |
25 #include "ui/views/corewm/window_util.h" | 25 #include "ui/views/corewm/window_util.h" |
26 | 26 |
27 using aura::Window; | 27 using aura::Window; |
28 | 28 |
29 namespace ash { | 29 namespace ash { |
30 | 30 |
31 namespace internal { | 31 namespace internal { |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 // This specifies how much percent (2/3=66%) of a window must be visible when | 35 // This specifies how much percent 30% of a window rect (width / height) |
36 // the window is added to the workspace. | 36 // must be visible when the window is added to the workspace. |
37 const float kMinimumPercentOnScreenArea = 0.66f; | 37 const float kMinimumPercentOnScreenArea = 0.3f; |
38 | 38 |
39 bool IsMaximizedState(ui::WindowShowState state) { | 39 bool IsMaximizedState(ui::WindowShowState state) { |
40 return state == ui::SHOW_STATE_MAXIMIZED || | 40 return state == ui::SHOW_STATE_MAXIMIZED || |
41 state == ui::SHOW_STATE_FULLSCREEN; | 41 state == ui::SHOW_STATE_FULLSCREEN; |
42 } | 42 } |
43 | 43 |
44 } // namespace | 44 } // namespace |
45 | 45 |
46 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window) | 46 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window) |
47 : BaseLayoutManager(window->GetRootWindow()), | 47 : BaseLayoutManager(window->GetRootWindow()), |
48 shelf_(NULL), | 48 shelf_(NULL), |
49 window_(window), | 49 window_(window), |
50 work_area_(ScreenAsh::GetDisplayWorkAreaBoundsInParent( | 50 work_area_(ScreenAsh::GetDisplayWorkAreaBoundsInParent( |
51 window->parent())) { | 51 window->parent())) { |
52 } | 52 } |
53 | 53 |
54 WorkspaceLayoutManager::~WorkspaceLayoutManager() { | 54 WorkspaceLayoutManager::~WorkspaceLayoutManager() { |
55 } | 55 } |
56 | 56 |
57 void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) { | 57 void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) { |
58 shelf_ = shelf; | 58 shelf_ = shelf; |
59 } | 59 } |
60 | 60 |
61 void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) { | 61 void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) { |
62 // Adjust window bounds in case that the new child is out of the workspace. | 62 // Adjust window bounds in case that the new child is given the bounds that |
63 AdjustWindowSizeForScreenChange(child, ADJUST_WINDOW_WINDOW_ADDED); | 63 // is out of the workspace. Exclude the case where bounds is empty |
64 // (this happens when a views::Widget is created), or the window | |
65 // is added with the bounds because a user explicitly moved to | |
66 // this position (drag and drop for example). | |
67 if (!child->bounds().IsEmpty() && | |
68 !wm::HasUserChangedWindowPositionOrSize(child)) | |
69 AdjustWindowBounds(child, ADJUST_WINDOW_WINDOW_ADDED); | |
64 BaseLayoutManager::OnWindowAddedToLayout(child); | 70 BaseLayoutManager::OnWindowAddedToLayout(child); |
65 UpdateDesktopVisibility(); | 71 UpdateDesktopVisibility(); |
66 RearrangeVisibleWindowOnShow(child); | 72 RearrangeVisibleWindowOnShow(child); |
67 } | 73 } |
68 | 74 |
69 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(Window* child) { | 75 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(Window* child) { |
70 BaseLayoutManager::OnWillRemoveWindowFromLayout(child); | 76 BaseLayoutManager::OnWillRemoveWindowFromLayout(child); |
71 if (child->TargetVisibility()) | 77 if (child->TargetVisibility()) |
72 RearrangeVisibleWindowOnHideOrRemove(child); | 78 RearrangeVisibleWindowOnHideOrRemove(child); |
73 } | 79 } |
(...skipping 29 matching lines...) Expand all Loading... | |
103 child_bounds.set_height( | 109 child_bounds.set_height( |
104 std::min(work_area_.height(), child_bounds.height())); | 110 std::min(work_area_.height(), child_bounds.height())); |
105 SetChildBoundsDirect(child, child_bounds); | 111 SetChildBoundsDirect(child, child_bounds); |
106 } | 112 } |
107 UpdateDesktopVisibility(); | 113 UpdateDesktopVisibility(); |
108 } | 114 } |
109 | 115 |
110 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { | 116 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { |
111 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( | 117 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( |
112 window_->parent())); | 118 window_->parent())); |
113 if (work_area != work_area_) | 119 if (work_area != work_area_) { |
114 AdjustWindowSizesForScreenChange(ADJUST_WINDOW_DISPLAY_INSETS_CHANGED); | 120 AdjustWindowsBoundsForWorkAreaChange( |
121 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED); | |
122 } | |
115 } | 123 } |
116 | 124 |
117 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, | 125 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, |
118 const void* key, | 126 const void* key, |
119 intptr_t old) { | 127 intptr_t old) { |
120 if (key == aura::client::kShowStateKey) { | 128 if (key == aura::client::kShowStateKey) { |
121 ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); | 129 ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); |
122 ui::WindowShowState new_state = | 130 ui::WindowShowState new_state = |
123 window->GetProperty(aura::client::kShowStateKey); | 131 window->GetProperty(aura::client::kShowStateKey); |
124 if (old_state != ui::SHOW_STATE_MINIMIZED && | 132 if (old_state != ui::SHOW_STATE_MINIMIZED && |
(...skipping 16 matching lines...) Expand all Loading... | |
141 SetRestoreBoundsInScreen(window, window->GetBoundsInScreen()); | 149 SetRestoreBoundsInScreen(window, window->GetBoundsInScreen()); |
142 } | 150 } |
143 | 151 |
144 UpdateBoundsFromShowState(window); | 152 UpdateBoundsFromShowState(window); |
145 ShowStateChanged(window, old_state); | 153 ShowStateChanged(window, old_state); |
146 | 154 |
147 // Set the restore rectangle to the previously set restore rectangle. | 155 // Set the restore rectangle to the previously set restore rectangle. |
148 if (!restore.IsEmpty()) | 156 if (!restore.IsEmpty()) |
149 SetRestoreBoundsInScreen(window, restore); | 157 SetRestoreBoundsInScreen(window, restore); |
150 } | 158 } |
151 | 159 oom |
Mr4D (OOO till 08-26)
2013/08/06 23:48:50
I guess this does not belong here.
| |
152 if (key == internal::kWindowTrackedByWorkspaceKey && | 160 if (key == internal::kWindowTrackedByWorkspaceKey && |
153 GetTrackedByWorkspace(window)) { | 161 GetTrackedByWorkspace(window)) { |
154 SetMaximizedOrFullscreenBounds(window); | 162 SetMaximizedOrFullscreenBounds(window); |
155 } | 163 } |
156 | 164 |
157 if (key == aura::client::kAlwaysOnTopKey && | 165 if (key == aura::client::kAlwaysOnTopKey && |
158 window->GetProperty(aura::client::kAlwaysOnTopKey)) { | 166 window->GetProperty(aura::client::kAlwaysOnTopKey)) { |
159 internal::AlwaysOnTopController* controller = | 167 internal::AlwaysOnTopController* controller = |
160 GetRootWindowController(window->GetRootWindow())-> | 168 GetRootWindowController(window->GetRootWindow())-> |
161 always_on_top_controller(); | 169 always_on_top_controller(); |
162 controller->GetContainer(window)->AddChild(window); | 170 controller->GetContainer(window)->AddChild(window); |
163 } | 171 } |
164 } | 172 } |
165 | 173 |
166 void WorkspaceLayoutManager::ShowStateChanged( | 174 void WorkspaceLayoutManager::ShowStateChanged( |
167 Window* window, | 175 Window* window, |
168 ui::WindowShowState last_show_state) { | 176 ui::WindowShowState last_show_state) { |
169 BaseLayoutManager::ShowStateChanged(window, last_show_state); | 177 BaseLayoutManager::ShowStateChanged(window, last_show_state); |
170 UpdateDesktopVisibility(); | 178 UpdateDesktopVisibility(); |
171 } | 179 } |
172 | 180 |
173 void WorkspaceLayoutManager::AdjustWindowSizesForScreenChange( | 181 void WorkspaceLayoutManager::AdjustWindowsBoundsForWorkAreaChange( |
174 AdjustWindowReason reason) { | 182 AdjustWindowReason reason) { |
175 work_area_ = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent()); | 183 work_area_ = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent()); |
176 BaseLayoutManager::AdjustWindowSizesForScreenChange(reason); | 184 BaseLayoutManager::AdjustWindowsBoundsForWorkAreaChange(reason); |
177 } | 185 } |
178 | 186 |
179 void WorkspaceLayoutManager::AdjustWindowSizeForScreenChange( | 187 void WorkspaceLayoutManager::AdjustWindowBounds( |
180 Window* window, | 188 Window* window, |
181 AdjustWindowReason reason) { | 189 AdjustWindowReason reason) { |
182 if (!GetTrackedByWorkspace(window)) | 190 if (!GetTrackedByWorkspace(window)) |
183 return; | 191 return; |
184 | 192 |
185 // Use cross fade transition for the maximized window if the adjustment | 193 // Use cross fade transition for the maximized window if the adjustment |
186 // happens due to the shelf's visibility change. Otherwise the background | 194 // happens due to the shelf's visibility change. Otherwise the background |
187 // can be seen slightly between the bottom edge of resized-window and | 195 // can be seen slightly between the bottom edge of resized-window and |
188 // the animating shelf. | 196 // the animating shelf. |
189 // TODO(mukai): this cause slight blur at the window frame because of the | 197 // TODO(mukai): this cause slight blur at the window frame because of the |
190 // cross fade. I think this is better, but should reconsider if someone | 198 // cross fade. I think this is better, but should reconsider if someone |
191 // raises voice for this. | 199 // raises voice for this. |
192 if (wm::IsWindowMaximized(window) && | 200 if (wm::IsWindowMaximized(window) && |
193 reason == ADJUST_WINDOW_DISPLAY_INSETS_CHANGED) { | 201 reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED) { |
194 CrossFadeToBounds(window, ScreenAsh::GetMaximizedWindowBoundsInParent( | 202 CrossFadeToBounds(window, ScreenAsh::GetMaximizedWindowBoundsInParent( |
195 window->parent()->parent())); | 203 window->parent()->parent())); |
196 return; | 204 return; |
197 } | 205 } |
198 | 206 |
199 if (SetMaximizedOrFullscreenBounds(window)) | 207 if (SetMaximizedOrFullscreenBounds(window)) |
200 return; | 208 return; |
201 | 209 |
202 gfx::Rect bounds = window->bounds(); | 210 gfx::Rect bounds = window->bounds(); |
203 if (reason == ADJUST_WINDOW_SCREEN_SIZE_CHANGED) { | 211 switch (reason) { |
204 // The work area may be smaller than the full screen. Put as much of the | 212 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED: |
205 // window as possible within the display area. | 213 // The work area may be smaller than the full screen. Put as much of the |
206 bounds.AdjustToFit(work_area_); | 214 // window as possible within the display area. |
207 } else if (reason == ADJUST_WINDOW_DISPLAY_INSETS_CHANGED) { | 215 bounds.AdjustToFit(work_area_); |
208 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_, &bounds); | 216 break; |
209 } else if (reason == ADJUST_WINDOW_WINDOW_ADDED) { | 217 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED: |
210 int min_width = bounds.width() * kMinimumPercentOnScreenArea; | 218 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_, &bounds); |
211 int min_height = bounds.height() * kMinimumPercentOnScreenArea; | 219 break; |
212 ash::wm::AdjustBoundsToEnsureWindowVisibility( | 220 case ADJUST_WINDOW_WINDOW_ADDED: { |
213 work_area_, min_width, min_height, &bounds); | 221 int min_width = bounds.width() * kMinimumPercentOnScreenArea; |
222 int min_height = bounds.height() * kMinimumPercentOnScreenArea; | |
223 ash::wm::AdjustBoundsToEnsureWindowVisibility( | |
224 work_area_, min_width, min_height, &bounds); | |
225 break; | |
226 } | |
214 } | 227 } |
215 if (window->bounds() != bounds) | 228 if (window->bounds() != bounds) |
216 window->SetBounds(bounds); | 229 window->SetBounds(bounds); |
217 } | 230 } |
218 | 231 |
219 void WorkspaceLayoutManager::UpdateDesktopVisibility() { | 232 void WorkspaceLayoutManager::UpdateDesktopVisibility() { |
220 if (shelf_) | 233 if (shelf_) |
221 shelf_->UpdateVisibilityState(); | 234 shelf_->UpdateVisibilityState(); |
222 FramePainter::UpdateSoloWindowHeader(window_->GetRootWindow()); | 235 FramePainter::UpdateSoloWindowHeader(window_->GetRootWindow()); |
223 } | 236 } |
224 | 237 |
225 void WorkspaceLayoutManager::UpdateBoundsFromShowState(Window* window) { | 238 void WorkspaceLayoutManager::UpdateBoundsFromShowState(Window* window) { |
226 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in | 239 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in |
227 // these calculation. | 240 // these calculation. |
228 switch (window->GetProperty(aura::client::kShowStateKey)) { | 241 switch (window->GetProperty(aura::client::kShowStateKey)) { |
229 case ui::SHOW_STATE_DEFAULT: | 242 case ui::SHOW_STATE_DEFAULT: |
230 case ui::SHOW_STATE_NORMAL: { | 243 case ui::SHOW_STATE_NORMAL: { |
231 const gfx::Rect* restore = GetRestoreBoundsInScreen(window); | 244 const gfx::Rect* restore = GetRestoreBoundsInScreen(window); |
245 // Make sure that the part of the window is always visible | |
246 // when restored. | |
247 gfx::Rect bounds_in_parent; | |
232 if (restore) { | 248 if (restore) { |
233 gfx::Rect bounds_in_parent = | 249 bounds_in_parent = |
234 ScreenAsh::ConvertRectFromScreen(window->parent()->parent(), | 250 ScreenAsh::ConvertRectFromScreen(window->parent()->parent(), |
235 *restore); | 251 *restore); |
252 | |
253 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( | |
254 work_area_, &bounds_in_parent); | |
255 } else { | |
256 // Minimized windows have no restore bounds. | |
257 // Use the current bounds instead. | |
258 bounds_in_parent = window->bounds(); | |
259 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( | |
260 work_area_, &bounds_in_parent); | |
261 // Don't start animation if the bounds didn't change. | |
262 if (bounds_in_parent == window->bounds()) | |
263 bounds_in_parent.SetRect(0, 0, 0, 0); | |
264 } | |
265 if (!bounds_in_parent.IsEmpty()) { | |
236 CrossFadeToBounds( | 266 CrossFadeToBounds( |
237 window, | 267 window, |
238 BaseLayoutManager::BoundsWithScreenEdgeVisible( | 268 BaseLayoutManager::BoundsWithScreenEdgeVisible( |
239 window->parent()->parent(), | 269 window->parent()->parent(), |
240 bounds_in_parent)); | 270 bounds_in_parent)); |
241 } | 271 } |
242 ClearRestoreBounds(window); | 272 ClearRestoreBounds(window); |
243 break; | 273 break; |
244 } | 274 } |
245 | 275 |
(...skipping 29 matching lines...) Expand all Loading... | |
275 SetChildBoundsDirect( | 305 SetChildBoundsDirect( |
276 window, | 306 window, |
277 ScreenAsh::GetDisplayBoundsInParent(window->parent()->parent())); | 307 ScreenAsh::GetDisplayBoundsInParent(window->parent()->parent())); |
278 return true; | 308 return true; |
279 } | 309 } |
280 return false; | 310 return false; |
281 } | 311 } |
282 | 312 |
283 } // namespace internal | 313 } // namespace internal |
284 } // namespace ash | 314 } // namespace ash |
OLD | NEW |