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

Side by Side Diff: ash/common/wm/window_positioning_utils.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 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
« no previous file with comments | « ash/common/wm/window_positioning_utils.h ('k') | ash/common/wm/window_resizer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 "ash/common/wm/window_positioning_utils.h"
6
7 #include <algorithm>
8
9 #include "ash/common/wm/system_modal_container_layout_manager.h"
10 #include "ash/common/wm/window_state.h"
11 #include "ash/common/wm/wm_event.h"
12 #include "ash/common/wm/wm_screen_util.h"
13 #include "ash/common/wm_shell.h"
14 #include "ash/common/wm_window.h"
15 #include "ash/root_window_controller.h"
16 #include "ash/shell.h"
17 #include "ui/aura/window_tracker.h"
18 #include "ui/display/display.h"
19 #include "ui/display/types/display_constants.h"
20 #include "ui/gfx/geometry/rect.h"
21 #include "ui/gfx/geometry/size.h"
22
23 namespace ash {
24 namespace wm {
25
26 namespace {
27
28 // Returns the default width of a snapped window.
29 int GetDefaultSnappedWindowWidth(WmWindow* window) {
30 const float kSnappedWidthWorkspaceRatio = 0.5f;
31
32 int work_area_width = GetDisplayWorkAreaBoundsInParent(window).width();
33 int min_width = window->GetMinimumSize().width();
34 int ideal_width =
35 static_cast<int>(work_area_width * kSnappedWidthWorkspaceRatio);
36 return std::min(work_area_width, std::max(ideal_width, min_width));
37 }
38
39 // Return true if the window or one of its ancestor returns true from
40 // IsLockedToRoot().
41 bool IsWindowOrAncestorLockedToRoot(const WmWindow* window) {
42 return window && (window->IsLockedToRoot() ||
43 IsWindowOrAncestorLockedToRoot(window->GetParent()));
44 }
45
46 // Move all transient children to |dst_root|, including the ones in
47 // the child windows and transient children of the transient children.
48 void MoveAllTransientChildrenToNewRoot(const display::Display& display,
49 WmWindow* window) {
50 WmWindow* dst_root =
51 Shell::GetRootWindowControllerWithDisplayId(display.id())->GetWindow();
52 for (WmWindow* transient_child : window->GetTransientChildren()) {
53 const int container_id = transient_child->GetParent()->GetShellWindowId();
54 DCHECK_GE(container_id, 0);
55 WmWindow* container = dst_root->GetChildByShellWindowId(container_id);
56 const gfx::Rect transient_child_bounds_in_screen =
57 transient_child->GetBoundsInScreen();
58 container->AddChild(transient_child);
59 transient_child->SetBoundsInScreen(transient_child_bounds_in_screen,
60 display);
61
62 // Transient children may have transient children.
63 MoveAllTransientChildrenToNewRoot(display, transient_child);
64 }
65 // Move transient children of the child windows if any.
66 for (WmWindow* child : window->GetChildren())
67 MoveAllTransientChildrenToNewRoot(display, child);
68 }
69
70 } // namespace
71
72 void AdjustBoundsSmallerThan(const gfx::Size& max_size, gfx::Rect* bounds) {
73 bounds->set_width(std::min(bounds->width(), max_size.width()));
74 bounds->set_height(std::min(bounds->height(), max_size.height()));
75 }
76
77 void AdjustBoundsToEnsureWindowVisibility(const gfx::Rect& visible_area,
78 int min_width,
79 int min_height,
80 gfx::Rect* bounds) {
81 AdjustBoundsSmallerThan(visible_area.size(), bounds);
82
83 min_width = std::min(min_width, visible_area.width());
84 min_height = std::min(min_height, visible_area.height());
85
86 if (bounds->right() < visible_area.x() + min_width) {
87 bounds->set_x(visible_area.x() + std::min(bounds->width(), min_width) -
88 bounds->width());
89 } else if (bounds->x() > visible_area.right() - min_width) {
90 bounds->set_x(visible_area.right() - std::min(bounds->width(), min_width));
91 }
92 if (bounds->bottom() < visible_area.y() + min_height) {
93 bounds->set_y(visible_area.y() + std::min(bounds->height(), min_height) -
94 bounds->height());
95 } else if (bounds->y() > visible_area.bottom() - min_height) {
96 bounds->set_y(visible_area.bottom() -
97 std::min(bounds->height(), min_height));
98 }
99 if (bounds->y() < visible_area.y())
100 bounds->set_y(visible_area.y());
101 }
102
103 void AdjustBoundsToEnsureMinimumWindowVisibility(const gfx::Rect& visible_area,
104 gfx::Rect* bounds) {
105 AdjustBoundsToEnsureWindowVisibility(visible_area, kMinimumOnScreenArea,
106 kMinimumOnScreenArea, bounds);
107 }
108
109 gfx::Rect GetDefaultLeftSnappedWindowBoundsInParent(WmWindow* window) {
110 gfx::Rect work_area_in_parent(GetDisplayWorkAreaBoundsInParent(window));
111 return gfx::Rect(work_area_in_parent.x(), work_area_in_parent.y(),
112 GetDefaultSnappedWindowWidth(window),
113 work_area_in_parent.height());
114 }
115
116 gfx::Rect GetDefaultRightSnappedWindowBoundsInParent(WmWindow* window) {
117 gfx::Rect work_area_in_parent(GetDisplayWorkAreaBoundsInParent(window));
118 int width = GetDefaultSnappedWindowWidth(window);
119 return gfx::Rect(work_area_in_parent.right() - width, work_area_in_parent.y(),
120 width, work_area_in_parent.height());
121 }
122
123 void CenterWindow(WmWindow* window) {
124 WMEvent event(WM_EVENT_CENTER);
125 window->GetWindowState()->OnWMEvent(&event);
126 }
127
128 void SetBoundsInScreen(WmWindow* window,
129 const gfx::Rect& bounds_in_screen,
130 const display::Display& display) {
131 DCHECK_NE(display::kInvalidDisplayId, display.id());
132 // Don't move a window to other root window if:
133 // a) the window is a transient window. It moves when its
134 // transient parent moves.
135 // b) if the window or its ancestor has IsLockedToRoot(). It's intentionally
136 // kept in the same root window even if the bounds is outside of the
137 // display.
138 if (!window->GetTransientParent() &&
139 !IsWindowOrAncestorLockedToRoot(window)) {
140 RootWindowController* dst_root_window_controller =
141 Shell::GetRootWindowControllerWithDisplayId(display.id());
142 DCHECK(dst_root_window_controller);
143 WmWindow* dst_root = dst_root_window_controller->GetWindow();
144 DCHECK(dst_root);
145 WmWindow* dst_container = nullptr;
146 if (dst_root != window->GetRootWindow()) {
147 int container_id = window->GetParent()->GetShellWindowId();
148 // All containers that uses screen coordinates must have valid window ids.
149 DCHECK_GE(container_id, 0);
150 // Don't move modal background.
151 if (!SystemModalContainerLayoutManager::IsModalBackground(window))
152 dst_container = dst_root->GetChildByShellWindowId(container_id);
153 }
154
155 if (dst_container && window->GetParent() != dst_container) {
156 WmWindow* focused = WmShell::Get()->GetFocusedWindow();
157 WmWindow* active = WmShell::Get()->GetActiveWindow();
158
159 aura::WindowTracker tracker;
160 if (focused)
161 tracker.Add(focused->aura_window());
162 if (active && focused != active)
163 tracker.Add(active->aura_window());
164
165 gfx::Point origin = bounds_in_screen.origin();
166 const gfx::Point display_origin = display.bounds().origin();
167 origin.Offset(-display_origin.x(), -display_origin.y());
168 gfx::Rect new_bounds = gfx::Rect(origin, bounds_in_screen.size());
169
170 // Set new bounds now so that the container's layout manager can adjust
171 // the bounds if necessary.
172 window->SetBounds(new_bounds);
173
174 dst_container->AddChild(window);
175
176 MoveAllTransientChildrenToNewRoot(display, window);
177
178 // Restore focused/active window.
179 if (focused && tracker.Contains(focused->aura_window())) {
180 focused->SetFocused();
181 WmShell::Get()->set_root_window_for_new_windows(
182 focused->GetRootWindow());
183 } else if (active && tracker.Contains(active->aura_window())) {
184 active->Activate();
185 }
186 // TODO(oshima): We should not have to update the bounds again
187 // below in theory, but we currently do need as there is a code
188 // that assumes that the bounds will never be overridden by the
189 // layout mananger. We should have more explicit control how
190 // constraints are applied by the layout manager.
191 }
192 }
193 gfx::Point origin(bounds_in_screen.origin());
194 const gfx::Point display_origin =
195 window->GetDisplayNearestWindow().bounds().origin();
196 origin.Offset(-display_origin.x(), -display_origin.y());
197 window->SetBounds(gfx::Rect(origin, bounds_in_screen.size()));
198 }
199
200 } // namespace wm
201 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/wm/window_positioning_utils.h ('k') | ash/common/wm/window_resizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698