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