1 // Copyright 2017 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/display/display_move_window_util.h"
6 
7 #include "ash/accelerators/accelerator_controller_impl.h"
8 #include "ash/accelerators/accelerator_table.h"
9 #include "ash/accessibility/test_accessibility_controller_client.h"
10 #include "ash/public/cpp/shelf_config.h"
11 #include "ash/root_window_controller.h"
12 #include "ash/screen_util.h"
13 #include "ash/shell.h"
14 #include "ash/test/ash_test_base.h"
15 #include "ash/wm/mru_window_tracker.h"
16 #include "ash/wm/window_state.h"
17 #include "ash/wm/window_util.h"
18 #include "ash/wm/wm_event.h"
19 #include "base/command_line.h"
20 #include "base/macros.h"
21 #include "ui/aura/test/test_windows.h"
22 #include "ui/display/display.h"
23 #include "ui/display/display_layout.h"
24 #include "ui/display/display_layout_builder.h"
25 #include "ui/display/manager/display_layout_store.h"
26 #include "ui/display/manager/display_manager.h"
27 #include "ui/display/screen.h"
28 #include "ui/display/test/display_manager_test_api.h"
29 #include "ui/views/widget/widget.h"
30 #include "ui/wm/core/window_util.h"
31 
32 namespace ash {
33 
34 namespace display_move_window_util {
35 
36 namespace {
37 
38 // Get the default left snapped window bounds which has snapped width ratio 0.5.
GetDefaultLeftSnappedBoundsInDisplay(const display::Display & display)39 gfx::Rect GetDefaultLeftSnappedBoundsInDisplay(
40     const display::Display& display) {
41   auto work_area = display.work_area();
42   work_area.set_width(work_area.width() / 2);
43   return work_area;
44 }
45 
CreateTestWidgetWithParent(views::Widget::InitParams::Type type,gfx::NativeView parent,const gfx::Rect & bounds,bool child)46 views::Widget* CreateTestWidgetWithParent(views::Widget::InitParams::Type type,
47                                           gfx::NativeView parent,
48                                           const gfx::Rect& bounds,
49                                           bool child) {
50   views::Widget::InitParams params(type);
51   params.delegate = nullptr;
52   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
53   params.parent = parent;
54   params.bounds = bounds;
55   params.child = child;
56   views::Widget* widget = new views::Widget;
57   widget->Init(std::move(params));
58   widget->Show();
59   return widget;
60 }
61 
PerformMoveWindowAccel()62 void PerformMoveWindowAccel() {
63   Shell::Get()->accelerator_controller()->PerformActionIfEnabled(
64       MOVE_ACTIVE_WINDOW_BETWEEN_DISPLAYS, {});
65 }
66 
67 }  // namespace
68 
69 using DisplayMoveWindowUtilTest = AshTestBase;
70 
TEST_F(DisplayMoveWindowUtilTest,SingleDisplay)71 TEST_F(DisplayMoveWindowUtilTest, SingleDisplay) {
72   aura::Window* window =
73       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
74   wm::ActivateWindow(window);
75   EXPECT_FALSE(CanHandleMoveActiveWindowBetweenDisplays());
76 }
77 
78 // Tests that window bounds are not changing after moving to another display. It
79 // is added as a child window to another root window with the same origin.
TEST_F(DisplayMoveWindowUtilTest,WindowBounds)80 TEST_F(DisplayMoveWindowUtilTest, WindowBounds) {
81   // Layout: [p][1]
82   UpdateDisplay("400x300,400x300");
83   aura::Window* window =
84       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
85   wm::ActivateWindow(window);
86   PerformMoveWindowAccel();
87   EXPECT_EQ(gfx::Rect(410, 20, 200, 100), window->GetBoundsInScreen());
88 }
89 
90 // Tests window state (maximized/fullscreen/snapped) and its bounds.
TEST_F(DisplayMoveWindowUtilTest,WindowState)91 TEST_F(DisplayMoveWindowUtilTest, WindowState) {
92   // Layout: [p][ 1 ]
93   UpdateDisplay("400x300,800x300");
94 
95   aura::Window* window =
96       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
97   wm::ActivateWindow(window);
98   display::Screen* screen = display::Screen::GetScreen();
99   ASSERT_EQ(display_manager()->GetDisplayAt(0).id(),
100             screen->GetDisplayNearestWindow(window).id());
101   WindowState* window_state = WindowState::Get(window);
102   // Set window to maximized state.
103   window_state->Maximize();
104   EXPECT_TRUE(window_state->IsMaximized());
105   EXPECT_EQ(screen_util::GetMaximizedWindowBoundsInParent(window),
106             window->bounds());
107   PerformMoveWindowAccel();
108   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
109             screen->GetDisplayNearestWindow(window).id());
110   // Check that window state is maximized and has updated maximized bounds.
111   EXPECT_TRUE(window_state->IsMaximized());
112   EXPECT_EQ(screen_util::GetMaximizedWindowBoundsInParent(window),
113             window->bounds());
114 
115   // Set window to fullscreen state.
116   PerformMoveWindowAccel();
117   const WMEvent fullscreen(WM_EVENT_TOGGLE_FULLSCREEN);
118   window_state->OnWMEvent(&fullscreen);
119   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
120             screen->GetDisplayNearestWindow(window).id());
121   EXPECT_TRUE(window_state->IsFullscreen());
122   EXPECT_EQ(display_manager()->GetDisplayAt(0).bounds(),
123             window->GetBoundsInScreen());
124   PerformMoveWindowAccel();
125   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
126             screen->GetDisplayNearestWindow(window).id());
127   // Check that window state is fullscreen and has updated fullscreen bounds.
128   EXPECT_TRUE(window_state->IsFullscreen());
129   EXPECT_EQ(display_manager()->GetDisplayAt(1).bounds(),
130             window->GetBoundsInScreen());
131 
132   // Set window to left snapped state.
133   PerformMoveWindowAccel();
134   const WMEvent snap_left(WM_EVENT_SNAP_LEFT);
135   window_state->OnWMEvent(&snap_left);
136   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
137             screen->GetDisplayNearestWindow(window).id());
138   EXPECT_TRUE(window_state->IsSnapped());
139   EXPECT_EQ(GetDefaultLeftSnappedBoundsInDisplay(
140                 screen->GetDisplayNearestWindow(window)),
141             window->GetBoundsInScreen());
142   EXPECT_EQ(0.5f, *window_state->snapped_width_ratio());
143   PerformMoveWindowAccel();
144   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
145             screen->GetDisplayNearestWindow(window).id());
146   // Check that window state is snapped and has updated snapped bounds.
147   EXPECT_TRUE(window_state->IsSnapped());
148   EXPECT_EQ(GetDefaultLeftSnappedBoundsInDisplay(
149                 screen->GetDisplayNearestWindow(window)),
150             window->GetBoundsInScreen());
151   EXPECT_EQ(0.5f, *window_state->snapped_width_ratio());
152 }
153 
154 // Tests that movement follows cycling through sorted display id list.
TEST_F(DisplayMoveWindowUtilTest,FourDisplays)155 TEST_F(DisplayMoveWindowUtilTest, FourDisplays) {
156   display::Screen* screen = display::Screen::GetScreen();
157   int64_t primary_id = screen->GetPrimaryDisplay().id();
158   // Layout:
159   // [3][2]
160   // [1][p]
161   display::DisplayIdList list =
162       display::test::CreateDisplayIdListN(primary_id, 4);
163   display::DisplayLayoutBuilder builder(primary_id);
164   builder.AddDisplayPlacement(list[1], primary_id,
165                               display::DisplayPlacement::LEFT, 0);
166   builder.AddDisplayPlacement(list[2], primary_id,
167                               display::DisplayPlacement::TOP, 0);
168   builder.AddDisplayPlacement(list[3], list[2], display::DisplayPlacement::LEFT,
169                               0);
170   display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
171       list, builder.Build());
172   UpdateDisplay("400x300,400x300,400x300,400x300");
173   EXPECT_EQ(4U, display_manager()->GetNumDisplays());
174   EXPECT_EQ(gfx::Rect(0, 0, 400, 300),
175             display_manager()->GetDisplayAt(0).bounds());
176   EXPECT_EQ(gfx::Rect(-400, 0, 400, 300),
177             display_manager()->GetDisplayAt(1).bounds());
178   EXPECT_EQ(gfx::Rect(0, -300, 400, 300),
179             display_manager()->GetDisplayAt(2).bounds());
180   EXPECT_EQ(gfx::Rect(-400, -300, 400, 300),
181             display_manager()->GetDisplayAt(3).bounds());
182 
183   aura::Window* window =
184       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
185   wm::ActivateWindow(window);
186   ASSERT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
187 
188   PerformMoveWindowAccel();
189   EXPECT_EQ(list[1], screen->GetDisplayNearestWindow(window).id());
190   PerformMoveWindowAccel();
191   EXPECT_EQ(list[2], screen->GetDisplayNearestWindow(window).id());
192   PerformMoveWindowAccel();
193   EXPECT_EQ(list[3], screen->GetDisplayNearestWindow(window).id());
194   PerformMoveWindowAccel();
195   EXPECT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
196 }
197 
198 // Tests that a11y alert is sent on handling move window to display.
TEST_F(DisplayMoveWindowUtilTest,A11yAlert)199 TEST_F(DisplayMoveWindowUtilTest, A11yAlert) {
200   // Layout: [p][1]
201   UpdateDisplay("400x300,400x300");
202   TestAccessibilityControllerClient client;
203 
204   aura::Window* window =
205       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
206   wm::ActivateWindow(window);
207   PerformMoveWindowAccel();
208   EXPECT_EQ(AccessibilityAlert::WINDOW_MOVED_TO_ANOTHER_DISPLAY,
209             client.last_a11y_alert());
210 }
211 
212 // Tests that moving window between displays is no-op if active window is not in
213 // window cycle list.
TEST_F(DisplayMoveWindowUtilTest,NoMovementIfNotInCycleWindowList)214 TEST_F(DisplayMoveWindowUtilTest, NoMovementIfNotInCycleWindowList) {
215   // Layout: [p][1]
216   UpdateDisplay("400x300,400x300");
217   // Create a window in app list container, which would be excluded in cycle
218   // window list.
219   std::unique_ptr<aura::Window> window = CreateChildWindow(
220       Shell::GetPrimaryRootWindow(), gfx::Rect(10, 20, 200, 100),
221       kShellWindowId_AppListContainer);
222   wm::ActivateWindow(window.get());
223   display::Screen* screen = display::Screen::GetScreen();
224   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
225             screen->GetDisplayNearestWindow(window.get()).id());
226 
227   MruWindowTracker::WindowList cycle_window_list =
228       Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kActiveDesk);
229   EXPECT_TRUE(cycle_window_list.empty());
230   PerformMoveWindowAccel();
231   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
232             screen->GetDisplayNearestWindow(window.get()).id());
233 }
234 
235 // Tests that window bounds should be kept if it is not changed by user, i.e.
236 // if it is changed by display area difference, it should restore to the
237 // original bounds when it is moved between displays and there is enough work
238 // area to show this window.
TEST_F(DisplayMoveWindowUtilTest,KeepWindowBoundsIfNotChangedByUser)239 TEST_F(DisplayMoveWindowUtilTest, KeepWindowBoundsIfNotChangedByUser) {
240   // Layout:
241   // +---+---+
242   // | p |   |
243   // +---+ 1 |
244   //     |   |
245   //     +---+
246   UpdateDisplay("400x300,400x600");
247   const int shelf_inset = 300 - ShelfConfig::Get()->shelf_size();
248   // Create and activate window on display [1].
249   aura::Window* window =
250       CreateTestWindowInShellWithBounds(gfx::Rect(410, 20, 200, 400));
251   wm::ActivateWindow(window);
252   display::Screen* screen = display::Screen::GetScreen();
253   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
254             screen->GetDisplayNearestWindow(window).id());
255   // Move window to display [p]. Its window bounds is adjusted by available work
256   // area.
257   PerformMoveWindowAccel();
258   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
259             screen->GetDisplayNearestWindow(window).id());
260   EXPECT_EQ(gfx::Rect(10, 20, 200, shelf_inset), window->GetBoundsInScreen());
261   // Move window back to display [1]. Its window bounds should be restored.
262   PerformMoveWindowAccel();
263   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
264             screen->GetDisplayNearestWindow(window).id());
265   EXPECT_EQ(gfx::Rect(410, 20, 200, 400), window->GetBoundsInScreen());
266 
267   // Move window to display [p] and set that its bounds is changed by user.
268   WindowState* window_state = WindowState::Get(window);
269   PerformMoveWindowAccel();
270   window_state->set_bounds_changed_by_user(true);
271   // Move window back to display [1], but its bounds has been changed by user.
272   // Then window bounds should be kept the same as that in display [p].
273   PerformMoveWindowAccel();
274   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
275             screen->GetDisplayNearestWindow(window).id());
276   EXPECT_EQ(gfx::Rect(410, 20, 200, shelf_inset), window->GetBoundsInScreen());
277 }
278 
279 // Tests auto window management on moving window between displays.
TEST_F(DisplayMoveWindowUtilTest,AutoManaged)280 TEST_F(DisplayMoveWindowUtilTest, AutoManaged) {
281   // Layout: [p][1]
282   UpdateDisplay("400x300,400x300");
283   // Create and show window on display [p]. Enable auto window position managed,
284   // which will center the window on display [p].
285   aura::Window* window1 =
286       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
287   WindowState* window1_state = WindowState::Get(window1);
288   window1_state->SetWindowPositionManaged(true);
289   window1->Hide();
290   window1->Show();
291   EXPECT_EQ(gfx::Rect(100, 20, 200, 100), window1->GetBoundsInScreen());
292   display::Screen* screen = display::Screen::GetScreen();
293   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
294             screen->GetDisplayNearestWindow(window1).id());
295 
296   // Create and show window on display [p]. Enable auto window position managed,
297   // which will do auto window management (pushing the other window to side).
298   aura::Window* window2 =
299       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
300   WindowState* window2_state = WindowState::Get(window2);
301   window2_state->SetWindowPositionManaged(true);
302   window2->Hide();
303   window2->Show();
304   EXPECT_EQ(gfx::Rect(0, 20, 200, 100), window1->GetBoundsInScreen());
305   EXPECT_EQ(gfx::Rect(200, 20, 200, 100), window2->GetBoundsInScreen());
306   // Activate window2.
307   wm::ActivateWindow(window2);
308   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
309             screen->GetDisplayNearestWindow(window2).id());
310   EXPECT_TRUE(window2_state->pre_auto_manage_window_bounds());
311   EXPECT_EQ(gfx::Rect(10, 20, 200, 100),
312             *window2_state->pre_auto_manage_window_bounds());
313 
314   // Move window2 to display [1] and check auto window management.
315   PerformMoveWindowAccel();
316   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
317             screen->GetDisplayNearestWindow(window2).id());
318   // Check |pre_added_to_workspace_window_bounds()|, which should be equal to
319   // |pre_auto_manage_window_bounds()| in this case.
320   EXPECT_EQ(*window2_state->pre_auto_manage_window_bounds(),
321             *window2_state->pre_added_to_workspace_window_bounds());
322   // Window 1 centers on display [p] again.
323   EXPECT_EQ(gfx::Rect(100, 20, 200, 100), window1->GetBoundsInScreen());
324   // Window 2 is positioned by |pre_added_to_workspace_window_bounds()|.
325   EXPECT_EQ(gfx::Rect(410, 20, 200, 100), window2->GetBoundsInScreen());
326 }
327 
TEST_F(DisplayMoveWindowUtilTest,WindowWithTransientChild)328 TEST_F(DisplayMoveWindowUtilTest, WindowWithTransientChild) {
329   UpdateDisplay("400x300,400x300");
330   aura::Window* window =
331       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
332   wm::ActivateWindow(window);
333 
334   // Create a |child| window and make it a transient child of |window|.
335   std::unique_ptr<aura::Window> child =
336       CreateChildWindow(window, gfx::Rect(20, 30, 40, 50));
337   ::wm::AddTransientChild(window, child.get());
338   display::Screen* screen = display::Screen::GetScreen();
339   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
340             screen->GetDisplayNearestWindow(window).id());
341   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
342             screen->GetDisplayNearestWindow(child.get()).id());
343 
344   // Operate moving window to right display. Check display and bounds.
345   PerformMoveWindowAccel();
346   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
347             screen->GetDisplayNearestWindow(window).id());
348   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
349             screen->GetDisplayNearestWindow(child.get()).id());
350   EXPECT_EQ(gfx::Rect(410, 20, 200, 100), window->GetBoundsInScreen());
351   EXPECT_EQ(gfx::Rect(430, 50, 40, 50), child->GetBoundsInScreen());
352 }
353 
354 // Test that when operating move window between displays on activated transient
355 // child window, its first non-transient transient-parent window should be the
356 // target instead.
TEST_F(DisplayMoveWindowUtilTest,ActiveTransientChildWindow)357 TEST_F(DisplayMoveWindowUtilTest, ActiveTransientChildWindow) {
358   UpdateDisplay("400x300,400x300");
359   std::unique_ptr<views::Widget> window = CreateTestWidget();
360   window->SetBounds(gfx::Rect(10, 20, 200, 100));
361 
362   // Create a |child| transient widget of |window|. When |child| is shown, it is
363   // activated.
364   std::unique_ptr<views::Widget> child(CreateTestWidgetWithParent(
365       views::Widget::InitParams::TYPE_WINDOW, window->GetNativeView(),
366       gfx::Rect(20, 30, 40, 50), false));
367   display::Screen* screen = display::Screen::GetScreen();
368   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
369             screen->GetDisplayNearestWindow(window->GetNativeWindow()).id());
370   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
371             screen->GetDisplayNearestWindow(child->GetNativeWindow()).id());
372   // Ensure |child| window is activated.
373   EXPECT_FALSE(wm::IsActiveWindow(window->GetNativeWindow()));
374   EXPECT_TRUE(wm::IsActiveWindow(child->GetNativeWindow()));
375 
376   // Operate moving window to right display. Check display and bounds.
377   PerformMoveWindowAccel();
378   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
379             screen->GetDisplayNearestWindow(window->GetNativeWindow()).id());
380   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
381             screen->GetDisplayNearestWindow(child->GetNativeWindow()).id());
382   EXPECT_EQ(gfx::Rect(410, 20, 200, 100),
383             window->GetNativeWindow()->GetBoundsInScreen());
384   EXPECT_EQ(gfx::Rect(420, 30, 40, 50),
385             child->GetNativeWindow()->GetBoundsInScreen());
386 }
387 
388 // Test that when active window is transient child window, no movement if its
389 // first non-transient transient-parent window is not in window cycle list.
TEST_F(DisplayMoveWindowUtilTest,TransientParentNotInCycleWindowList)390 TEST_F(DisplayMoveWindowUtilTest, TransientParentNotInCycleWindowList) {
391   UpdateDisplay("400x300,400x300");
392   aura::Window* w1 =
393       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 50, 50));
394   wm::ActivateWindow(w1);
395 
396   // Create a window |w2| in non-switchable window container.
397   aura::Window* setting_bubble_container =
398       Shell::GetPrimaryRootWindowController()->GetContainer(
399           kShellWindowId_SettingBubbleContainer);
400   std::unique_ptr<aura::Window> w2 = CreateChildWindow(
401       setting_bubble_container, gfx::Rect(10, 20, 200, 100), -1);
402   wm::ActivateWindow(w2.get());
403 
404   // Create a |child| transient widget of |w2|. When |child| is shown, it is
405   // activated.
406   std::unique_ptr<views::Widget> child(
407       CreateTestWidgetWithParent(views::Widget::InitParams::TYPE_WINDOW,
408                                  w2.get(), gfx::Rect(20, 30, 40, 50), false));
409   display::Screen* screen = display::Screen::GetScreen();
410   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
411             screen->GetDisplayNearestWindow(w1).id());
412   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
413             screen->GetDisplayNearestWindow(w2.get()).id());
414   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
415             screen->GetDisplayNearestWindow(child->GetNativeWindow()).id());
416   // Ensure |child| window is activated.
417   EXPECT_FALSE(wm::IsActiveWindow(w1));
418   EXPECT_FALSE(wm::IsActiveWindow(w2.get()));
419   EXPECT_TRUE(wm::IsActiveWindow(child->GetNativeWindow()));
420 
421   PerformMoveWindowAccel();
422   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
423             screen->GetDisplayNearestWindow(w1).id());
424   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
425             screen->GetDisplayNearestWindow(w2.get()).id());
426   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
427             screen->GetDisplayNearestWindow(child->GetNativeWindow()).id());
428 }
429 
430 // Tests that restore bounds is updated with window movement to another display.
TEST_F(DisplayMoveWindowUtilTest,RestoreMaximizedWindowAfterMovement)431 TEST_F(DisplayMoveWindowUtilTest, RestoreMaximizedWindowAfterMovement) {
432   UpdateDisplay("400x300,400x300");
433   aura::Window* w =
434       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
435   wm::ActivateWindow(w);
436 
437   WindowState* window_state = WindowState::Get(w);
438   window_state->Maximize();
439   EXPECT_EQ(gfx::Rect(0, 0, 400, 300 - ShelfConfig::Get()->shelf_size()),
440             w->GetBoundsInScreen());
441 
442   PerformMoveWindowAccel();
443   EXPECT_EQ(gfx::Rect(400, 0, 400, 300 - ShelfConfig::Get()->shelf_size()),
444             w->GetBoundsInScreen());
445   window_state->Restore();
446   EXPECT_EQ(gfx::Rect(410, 20, 200, 100), w->GetBoundsInScreen());
447 }
448 
449 }  // namespace display_move_window_util
450 
451 }  // namespace ash
452