1 // Copyright 2014 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/screen_util.h"
6
7 #include "ash/display/display_configuration_controller.h"
8 #include "ash/display/mirror_window_controller.h"
9 #include "ash/display/window_tree_host_manager.h"
10 #include "ash/public/cpp/shell_window_ids.h"
11 #include "ash/shelf/shelf.h"
12 #include "ash/shell.h"
13 #include "ash/wm/desks/desks_util.h"
14 #include "ash/wm/work_area_insets.h"
15 #include "base/check_op.h"
16 #include "ui/aura/client/screen_position_client.h"
17 #include "ui/aura/window_event_dispatcher.h"
18 #include "ui/aura/window_tree_host.h"
19 #include "ui/display/display.h"
20 #include "ui/display/manager/display_manager.h"
21 #include "ui/display/screen.h"
22 #include "ui/gfx/geometry/size_conversions.h"
23 #include "ui/wm/core/coordinate_conversion.h"
24
25 namespace ash {
26
27 namespace screen_util {
28
GetMaximizedWindowBoundsInParent(aura::Window * window)29 gfx::Rect GetMaximizedWindowBoundsInParent(aura::Window* window) {
30 if (Shelf::ForWindow(window)->shelf_widget())
31 return GetDisplayWorkAreaBoundsInParent(window);
32 return GetDisplayBoundsInParent(window);
33 }
34
GetDisplayBoundsInParent(aura::Window * window)35 gfx::Rect GetDisplayBoundsInParent(aura::Window* window) {
36 gfx::Rect result =
37 display::Screen::GetScreen()->GetDisplayNearestWindow(window).bounds();
38 ::wm::ConvertRectFromScreen(window->parent(), &result);
39 return result;
40 }
41
GetFullscreenWindowBoundsInParent(aura::Window * window)42 gfx::Rect GetFullscreenWindowBoundsInParent(aura::Window* window) {
43 gfx::Rect result = GetDisplayBoundsInParent(window);
44 const WorkAreaInsets* const work_area_insets =
45 WorkAreaInsets::ForWindow(window->GetRootWindow());
46 result.Inset(0,
47 work_area_insets->accessibility_panel_height() +
48 work_area_insets->docked_magnifier_height(),
49 0, 0);
50 return result;
51 }
52
GetDisplayWorkAreaBoundsInParent(aura::Window * window)53 gfx::Rect GetDisplayWorkAreaBoundsInParent(aura::Window* window) {
54 gfx::Rect result =
55 display::Screen::GetScreen()->GetDisplayNearestWindow(window).work_area();
56 ::wm::ConvertRectFromScreen(window->parent(), &result);
57 return result;
58 }
59
GetDisplayWorkAreaBoundsInParentForLockScreen(aura::Window * window)60 gfx::Rect GetDisplayWorkAreaBoundsInParentForLockScreen(aura::Window* window) {
61 gfx::Rect bounds = WorkAreaInsets::ForWindow(window)->user_work_area_bounds();
62 ::wm::ConvertRectFromScreen(window->parent(), &bounds);
63 return bounds;
64 }
65
GetDisplayWorkAreaBoundsInParentForActiveDeskContainer(aura::Window * window)66 gfx::Rect GetDisplayWorkAreaBoundsInParentForActiveDeskContainer(
67 aura::Window* window) {
68 aura::Window* root_window = window->GetRootWindow();
69 return GetDisplayWorkAreaBoundsInParent(
70 desks_util::GetActiveDeskContainerForRoot(root_window));
71 }
72
GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(aura::Window * window)73 gfx::Rect GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
74 aura::Window* window) {
75 gfx::Rect bounds =
76 GetDisplayWorkAreaBoundsInParentForActiveDeskContainer(window);
77 ::wm::ConvertRectToScreen(window->GetRootWindow(), &bounds);
78 return bounds;
79 }
80
GetDisplayBoundsWithShelf(aura::Window * window)81 gfx::Rect GetDisplayBoundsWithShelf(aura::Window* window) {
82 if (!Shell::Get()->display_manager()->IsInUnifiedMode()) {
83 return display::Screen::GetScreen()
84 ->GetDisplayNearestWindow(window)
85 .bounds();
86 }
87
88 // In Unified Mode, the display that should contain the shelf depends on the
89 // current shelf alignment.
90 const display::Display shelf_display =
91 Shell::Get()
92 ->display_configuration_controller()
93 ->GetPrimaryMirroringDisplayForUnifiedDesktop();
94 DCHECK_NE(shelf_display.id(), display::kInvalidDisplayId);
95 gfx::RectF shelf_display_screen_bounds(shelf_display.bounds());
96
97 // Transform the bounds back to the unified host's coordinates.
98 auto inverse_unified_transform =
99 window->GetRootWindow()->GetHost()->GetInverseRootTransform();
100 inverse_unified_transform.TransformRect(&shelf_display_screen_bounds);
101
102 return gfx::ToEnclosingRect(shelf_display_screen_bounds);
103 }
104
SnapBoundsToDisplayEdge(const gfx::Rect & bounds,const aura::Window * window)105 gfx::Rect SnapBoundsToDisplayEdge(const gfx::Rect& bounds,
106 const aura::Window* window) {
107 display::Display display =
108 display::Screen::GetScreen()->GetDisplayNearestWindow(
109 const_cast<aura::Window*>(window));
110
111 const float dsf = display.device_scale_factor();
112 const gfx::Size display_size_in_pixel = display.GetSizeInPixel();
113 const gfx::Size scaled_size_in_pixel =
114 gfx::ScaleToFlooredSize(display.size(), dsf);
115
116 // Adjusts |bounds| such that the scaled enclosed bounds are atleast as big as
117 // the scaled enclosing unadjusted bounds.
118 gfx::Rect snapped_bounds = bounds;
119 if (scaled_size_in_pixel.width() < display_size_in_pixel.width() &&
120 display.bounds().right() == bounds.right()) {
121 snapped_bounds.Inset(0, 0, -1, 0);
122 DCHECK_GE(gfx::ScaleToEnclosedRect(snapped_bounds, dsf).right(),
123 gfx::ScaleToEnclosingRect(bounds, dsf).right());
124 }
125 if (scaled_size_in_pixel.height() < display_size_in_pixel.height() &&
126 display.bounds().bottom() == bounds.bottom()) {
127 snapped_bounds.Inset(0, 0, 0, -1);
128 DCHECK_GE(gfx::ScaleToEnclosedRect(snapped_bounds, dsf).bottom(),
129 gfx::ScaleToEnclosingRect(bounds, dsf).bottom());
130 }
131
132 return snapped_bounds;
133 }
134
135 } // namespace screen_util
136
137 } // namespace ash
138