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

Side by Side Diff: ash/wm/workspace/workspace_layout_manager.cc

Issue 9113045: Reworks the workspace code. Here's the new heuristics: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged and all that good stuff. Created 8 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/wm/property_util.h" 7 #include "ash/wm/property_util.h"
8 #include "ash/wm/show_state_controller.h"
9 #include "ash/wm/window_util.h" 8 #include "ash/wm/window_util.h"
10 #include "ash/wm/workspace/workspace.h" 9 #include "ash/wm/workspace/workspace.h"
11 #include "ash/wm/workspace/workspace_manager.h" 10 #include "ash/wm/workspace/workspace_manager.h"
12 #include "ui/aura/client/aura_constants.h" 11 #include "ui/aura/client/aura_constants.h"
13 #include "ui/aura/event.h" 12 #include "ui/aura/event.h"
14 #include "ui/aura/root_window.h" 13 #include "ui/aura/root_window.h"
15 #include "ui/aura/screen_aura.h" 14 #include "ui/aura/screen_aura.h"
16 #include "ui/aura/window.h" 15 #include "ui/aura/window.h"
17 #include "ui/aura/window_observer.h" 16 #include "ui/aura/window_observer.h"
18 #include "ui/base/ui_base_types.h" 17 #include "ui/base/ui_base_types.h"
19 #include "ui/gfx/rect.h" 18 #include "ui/gfx/rect.h"
20 #include "ui/views/widget/native_widget_aura.h" 19 #include "ui/views/widget/native_widget_aura.h"
21 20
22 namespace ash { 21 namespace ash {
23 namespace internal { 22 namespace internal {
24 23
25 //////////////////////////////////////////////////////////////////////////////// 24 ////////////////////////////////////////////////////////////////////////////////
26 // WorkspaceLayoutManager, public: 25 // WorkspaceLayoutManager, public:
27 26
28 WorkspaceLayoutManager::WorkspaceLayoutManager( 27 WorkspaceLayoutManager::WorkspaceLayoutManager(
29 WorkspaceManager* workspace_manager) 28 WorkspaceManager* workspace_manager)
30 : workspace_manager_(workspace_manager), 29 : workspace_manager_(workspace_manager) {
31 show_state_controller_(new ShowStateController(workspace_manager)) {
32 } 30 }
33 31
34 WorkspaceLayoutManager::~WorkspaceLayoutManager() {} 32 WorkspaceLayoutManager::~WorkspaceLayoutManager() {}
35 33
36 void WorkspaceLayoutManager::PrepareForMoveOrResize( 34 void WorkspaceLayoutManager::PrepareForMoveOrResize(
37 aura::Window* drag, 35 aura::Window* drag,
38 aura::MouseEvent* event) { 36 aura::MouseEvent* event) {
39 workspace_manager_->set_ignored_window(drag); 37 workspace_manager_->set_ignored_window(drag);
40 } 38 }
41 39
42 void WorkspaceLayoutManager::CancelMoveOrResize( 40 void WorkspaceLayoutManager::CancelMoveOrResize(
43 aura::Window* drag, 41 aura::Window* drag,
44 aura::MouseEvent* event) { 42 aura::MouseEvent* event) {
45 workspace_manager_->set_ignored_window(NULL); 43 workspace_manager_->set_ignored_window(NULL);
46 } 44 }
47 45
48 void WorkspaceLayoutManager::ProcessMove( 46 void WorkspaceLayoutManager::ProcessMove(
49 aura::Window* drag, 47 aura::Window* drag,
50 aura::MouseEvent* event) { 48 aura::MouseEvent* event) {
51 // TODO(oshima): Just zooming out may (and will) move/swap window without 49 // TODO: needs implementation for TYPE_SPLIT. For TYPE_SPLIT I want to
52 // a users's intent. We probably should scroll viewport, but that may not 50 // disallow eventfilter from moving and instead deal with it here.
53 // be enough. See crbug.com/101826 for more discussion.
54 workspace_manager_->SetOverview(true);
55
56 gfx::Point point_in_owner = event->location();
57 aura::Window::ConvertPointToWindow(
58 drag,
59 workspace_manager_->contents_view(),
60 &point_in_owner);
61 // TODO(oshima): We should support simply moving to another
62 // workspace when the destination workspace has enough room to accomodate.
63 aura::Window* rotate_target =
64 workspace_manager_->FindRotateWindowForLocation(point_in_owner);
65 if (rotate_target)
66 workspace_manager_->RotateWindows(drag, rotate_target);
67 } 51 }
68 52
69 void WorkspaceLayoutManager::EndMove( 53 void WorkspaceLayoutManager::EndMove(
70 aura::Window* drag, 54 aura::Window* drag,
71 aura::MouseEvent* evnet) { 55 aura::MouseEvent* evnet) {
72 // TODO(oshima): finish moving window between workspaces. 56 // TODO: see comment in ProcessMove.
73 workspace_manager_->set_ignored_window(NULL); 57 workspace_manager_->set_ignored_window(NULL);
74 Workspace* workspace = workspace_manager_->FindBy(drag);
75 workspace->Layout(NULL);
76 workspace->Activate();
77 workspace_manager_->SetOverview(false);
78 } 58 }
79 59
80 void WorkspaceLayoutManager::EndResize( 60 void WorkspaceLayoutManager::EndResize(
81 aura::Window* drag, 61 aura::Window* drag,
82 aura::MouseEvent* evnet) { 62 aura::MouseEvent* evnet) {
63 // TODO: see comment in ProcessMove.
83 workspace_manager_->set_ignored_window(NULL); 64 workspace_manager_->set_ignored_window(NULL);
84 Workspace* workspace = workspace_manager_->GetActiveWorkspace();
85 if (workspace)
86 workspace->Layout(NULL);
87 workspace_manager_->SetOverview(false);
88 } 65 }
89 66
90 //////////////////////////////////////////////////////////////////////////////// 67 ////////////////////////////////////////////////////////////////////////////////
91 // WorkspaceLayoutManager, aura::LayoutManager implementation: 68 // WorkspaceLayoutManager, aura::LayoutManager implementation:
92 69
93 void WorkspaceLayoutManager::OnWindowResized() { 70 void WorkspaceLayoutManager::OnWindowResized() {
94 // Workspace is updated via RootWindowObserver::OnRootWindowResized. 71 // Workspace is updated via RootWindowObserver::OnRootWindowResized.
95 } 72 }
96 73
97 void WorkspaceLayoutManager::OnWindowAddedToLayout(aura::Window* child) { 74 void WorkspaceLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
98 if (child->type() != aura::client::WINDOW_TYPE_NORMAL || 75 if (!workspace_manager_->IsManagedWindow(child))
99 child->transient_parent()) {
100 return; 76 return;
101 }
102 77
103 if (!child->GetProperty(aura::client::kShowStateKey)) 78 if (child->IsVisible())
104 child->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 79 workspace_manager_->AddWindow(child);
105
106 child->AddObserver(show_state_controller_.get());
107
108 Workspace* workspace = workspace_manager_->GetActiveWorkspace();
109 if (workspace) {
110 aura::Window* active = ash::GetActiveWindow();
111 // Active window may not be in the default container layer.
112 if (!workspace->Contains(active))
113 active = NULL;
114 if (workspace->AddWindowAfter(child, active))
115 return;
116 }
117 // Create new workspace if new |child| doesn't fit to current workspace.
118 Workspace* new_workspace = workspace_manager_->CreateWorkspace();
119 new_workspace->AddWindowAfter(child, NULL);
120 new_workspace->Activate();
121 } 80 }
122 81
123 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout( 82 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(
124 aura::Window* child) { 83 aura::Window* child) {
125 child->RemoveObserver(show_state_controller_.get());
126 ClearRestoreBounds(child); 84 ClearRestoreBounds(child);
127 85 workspace_manager_->RemoveWindow(child);
128 Workspace* workspace = workspace_manager_->FindBy(child);
129 if (!workspace)
130 return;
131 workspace->RemoveWindow(child);
132 if (workspace->is_empty())
133 delete workspace;
134 } 86 }
135 87
136 void WorkspaceLayoutManager::OnChildWindowVisibilityChanged( 88 void WorkspaceLayoutManager::OnChildWindowVisibilityChanged(
137 aura::Window* child, 89 aura::Window* child,
138 bool visible) { 90 bool visible) {
139 NOTIMPLEMENTED(); 91 if (!workspace_manager_->IsManagedWindow(child))
92 return;
93 if (visible)
94 workspace_manager_->AddWindow(child);
95 else
96 workspace_manager_->RemoveWindow(child);
140 } 97 }
141 98
142 void WorkspaceLayoutManager::SetChildBounds( 99 void WorkspaceLayoutManager::SetChildBounds(
143 aura::Window* child, 100 aura::Window* child,
144 const gfx::Rect& requested_bounds) { 101 const gfx::Rect& requested_bounds) {
145 gfx::Rect adjusted_bounds = requested_bounds; 102 // Allow setting the bounds for any window we don't care about, isn't visible,
146 103 // or we're setting the bounds of. All other request are dropped on the floor.
147 // First, calculate the adjusted bounds. 104 if (child == workspace_manager_->ignored_window() ||
148 if (child->type() != aura::client::WINDOW_TYPE_NORMAL || 105 !workspace_manager_->IsManagedWindow(child) || !child->IsVisible() ||
149 workspace_manager_->layout_in_progress() || 106 (!window_util::IsWindowMaximized(child) &&
150 child->transient_parent()) { 107 !window_util::IsWindowFullscreen(child))) {
151 // Use the requested bounds as is. 108 SetChildBoundsDirect(child, requested_bounds);
152 } else if (child == workspace_manager_->ignored_window()) {
153 // If a drag window is requesting bounds, make sure its attached to
154 // the workarea's top and fits within the total drag area.
155 gfx::Rect drag_area = workspace_manager_->GetDragAreaBounds();
156 adjusted_bounds.set_y(drag_area.y());
157 adjusted_bounds = adjusted_bounds.AdjustToFit(drag_area);
158 } else {
159 Workspace* workspace = workspace_manager_->FindBy(child);
160 gfx::Rect work_area = workspace->GetWorkAreaBounds();
161 adjusted_bounds.set_origin(
162 gfx::Point(child->GetTargetBounds().x(), work_area.y()));
163 adjusted_bounds = adjusted_bounds.AdjustToFit(work_area);
164 } 109 }
165
166 ui::WindowShowState show_state = static_cast<ui::WindowShowState>(
167 child->GetIntProperty(aura::client::kShowStateKey));
168
169 // Second, check if the window is either maximized or in fullscreen mode.
170 if (show_state == ui::SHOW_STATE_MAXIMIZED ||
171 show_state == ui::SHOW_STATE_FULLSCREEN) {
172 // If the request is not from workspace manager,
173 // remember the requested bounds.
174 if (!workspace_manager_->layout_in_progress())
175 SetRestoreBounds(child, adjusted_bounds);
176
177 Workspace* workspace = workspace_manager_->FindBy(child);
178 if (show_state == ui::SHOW_STATE_MAXIMIZED)
179 adjusted_bounds = workspace->GetWorkAreaBounds();
180 else
181 adjusted_bounds = workspace->bounds();
182 // Don't
183 if (child->GetTargetBounds() == adjusted_bounds)
184 return;
185 }
186 SetChildBoundsDirect(child, adjusted_bounds);
187 } 110 }
188 111
189 } // namespace internal 112 } // namespace internal
190 } // namespace ash 113 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/workspace/workspace_layout_manager.h ('k') | ash/wm/workspace/workspace_layout_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698