screen_util.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. #include "ash/screen_util.h"
  5. #include "ash/display/display_configuration_controller.h"
  6. #include "ash/display/mirror_window_controller.h"
  7. #include "ash/display/window_tree_host_manager.h"
  8. #include "ash/public/cpp/shell_window_ids.h"
  9. #include "ash/shelf/shelf.h"
  10. #include "ash/shell.h"
  11. #include "ash/wm/desks/desks_util.h"
  12. #include "ash/wm/window_state.h"
  13. #include "ash/wm/work_area_insets.h"
  14. #include "base/check_op.h"
  15. #include "ui/aura/client/screen_position_client.h"
  16. #include "ui/aura/window_event_dispatcher.h"
  17. #include "ui/aura/window_tree_host.h"
  18. #include "ui/display/display.h"
  19. #include "ui/display/manager/display_manager.h"
  20. #include "ui/display/screen.h"
  21. #include "ui/gfx/geometry/size_conversions.h"
  22. #include "ui/wm/core/coordinate_conversion.h"
  23. namespace ash {
  24. namespace screen_util {
  25. gfx::Rect GetMaximizedWindowBoundsInParent(aura::Window* window) {
  26. if (Shelf::ForWindow(window)->shelf_widget())
  27. return GetDisplayWorkAreaBoundsInParent(window);
  28. return GetDisplayBoundsInParent(window);
  29. }
  30. gfx::Rect GetDisplayBoundsInParent(aura::Window* window) {
  31. gfx::Rect result =
  32. display::Screen::GetScreen()->GetDisplayNearestWindow(window).bounds();
  33. ::wm::ConvertRectFromScreen(window->parent(), &result);
  34. return result;
  35. }
  36. gfx::Rect GetFullscreenWindowBoundsInParent(aura::Window* window) {
  37. gfx::Rect result = GetDisplayBoundsInParent(window);
  38. const WorkAreaInsets* const work_area_insets =
  39. WorkAreaInsets::ForWindow(window->GetRootWindow());
  40. result.Inset(
  41. gfx::Insets().set_top(work_area_insets->accessibility_panel_height() +
  42. work_area_insets->docked_magnifier_height()));
  43. return result;
  44. }
  45. gfx::Rect GetDisplayWorkAreaBoundsInParent(aura::Window* window) {
  46. // If it is application window under `non_lock_screen_containers`, use
  47. // `in_session_user_work_area_insets`, otherwise, use `user_work_area_insets`.
  48. const aura::Window* non_lock_screen_containers = Shell::GetContainer(
  49. window->GetRootWindow(), kShellWindowId_NonLockScreenContainersContainer);
  50. gfx::Insets insets =
  51. non_lock_screen_containers->Contains(window)
  52. ? WorkAreaInsets::ForWindow(window)
  53. ->in_session_user_work_area_insets()
  54. : WorkAreaInsets::ForWindow(window)->user_work_area_insets();
  55. gfx::Rect bounds =
  56. display::Screen::GetScreen()->GetDisplayNearestWindow(window).bounds();
  57. bounds.Inset(insets);
  58. ::wm::ConvertRectFromScreen(window->parent(), &bounds);
  59. return bounds;
  60. }
  61. // TODO(yongshun): Remove or consolidate this function with
  62. // `GetDisplayWorkAreaBoundsInParent`.
  63. gfx::Rect GetDisplayWorkAreaBoundsInParentForLockScreen(aura::Window* window) {
  64. gfx::Rect bounds = WorkAreaInsets::ForWindow(window)->user_work_area_bounds();
  65. ::wm::ConvertRectFromScreen(window->parent(), &bounds);
  66. return bounds;
  67. }
  68. // TODO(yongshun): Remove or consolidate this function with
  69. // `GetDisplayWorkAreaBoundsInParent`.
  70. gfx::Rect GetDisplayWorkAreaBoundsInParentForActiveDeskContainer(
  71. aura::Window* window) {
  72. aura::Window* root_window = window->GetRootWindow();
  73. return GetDisplayWorkAreaBoundsInParent(
  74. desks_util::GetActiveDeskContainerForRoot(root_window));
  75. }
  76. // TODO(yongshun): Remove or consolidate this function with
  77. // `GetDisplayWorkAreaBoundsInParent`.
  78. gfx::Rect GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
  79. aura::Window* window) {
  80. gfx::Rect bounds =
  81. GetDisplayWorkAreaBoundsInParentForActiveDeskContainer(window);
  82. ::wm::ConvertRectToScreen(window->GetRootWindow(), &bounds);
  83. return bounds;
  84. }
  85. gfx::Rect GetDisplayBoundsWithShelf(aura::Window* window) {
  86. if (!Shell::Get()->display_manager()->IsInUnifiedMode()) {
  87. return display::Screen::GetScreen()
  88. ->GetDisplayNearestWindow(window)
  89. .bounds();
  90. }
  91. // In Unified Mode, the display that should contain the shelf depends on the
  92. // current shelf alignment.
  93. const display::Display shelf_display =
  94. Shell::Get()
  95. ->display_configuration_controller()
  96. ->GetPrimaryMirroringDisplayForUnifiedDesktop();
  97. DCHECK_NE(shelf_display.id(), display::kInvalidDisplayId);
  98. gfx::RectF shelf_display_screen_bounds(shelf_display.bounds());
  99. // Transform the bounds back to the unified host's coordinates.
  100. auto inverse_unified_transform =
  101. window->GetRootWindow()->GetHost()->GetInverseRootTransform();
  102. inverse_unified_transform.TransformRect(&shelf_display_screen_bounds);
  103. return gfx::ToEnclosingRect(shelf_display_screen_bounds);
  104. }
  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. const float dsf = display.device_scale_factor();
  111. const gfx::Size display_size_in_pixel = display.GetSizeInPixel();
  112. const gfx::Size scaled_size_in_pixel =
  113. gfx::ScaleToFlooredSize(display.size(), dsf);
  114. // Adjusts |bounds| such that the scaled enclosed bounds are atleast as big as
  115. // the scaled enclosing unadjusted bounds.
  116. gfx::Rect snapped_bounds = bounds;
  117. if (scaled_size_in_pixel.width() < display_size_in_pixel.width() &&
  118. display.bounds().right() == bounds.right()) {
  119. snapped_bounds.Inset(gfx::Insets::TLBR(0, 0, 0, -1));
  120. DCHECK_GE(gfx::ScaleToEnclosedRect(snapped_bounds, dsf).right(),
  121. gfx::ScaleToEnclosingRect(bounds, dsf).right());
  122. }
  123. if (scaled_size_in_pixel.height() < display_size_in_pixel.height() &&
  124. display.bounds().bottom() == bounds.bottom()) {
  125. snapped_bounds.Inset(gfx::Insets::TLBR(0, 0, -1, 0));
  126. DCHECK_GE(gfx::ScaleToEnclosedRect(snapped_bounds, dsf).bottom(),
  127. gfx::ScaleToEnclosingRect(bounds, dsf).bottom());
  128. }
  129. return snapped_bounds;
  130. }
  131. gfx::Rect GetIdealBoundsForMaximizedOrFullscreenOrPinnedState(
  132. aura::Window* window) {
  133. auto* window_state = WindowState::Get(window);
  134. if (window_state->IsMaximized()) {
  135. auto* shelf = ash::Shelf::ForWindow(window);
  136. if (shelf->auto_hide_behavior() == ash::ShelfAutoHideBehavior::kAlways) {
  137. gfx::Rect bounds =
  138. ash::screen_util::GetFullscreenWindowBoundsInParent(window);
  139. ::wm::ConvertRectToScreen(window->parent(), &bounds);
  140. return bounds;
  141. }
  142. if (shelf->auto_hide_behavior() ==
  143. ash::ShelfAutoHideBehavior::kAlwaysHidden) {
  144. return display::Screen::GetScreen()
  145. ->GetDisplayNearestWindow(const_cast<aura::Window*>(window))
  146. .work_area();
  147. }
  148. auto work_area =
  149. ash::WorkAreaInsets::ForWindow(window)->ComputeStableWorkArea();
  150. return work_area;
  151. }
  152. if (window_state->IsFullscreen() || window_state->IsPinned()) {
  153. gfx::Rect bounds =
  154. ash::screen_util::GetFullscreenWindowBoundsInParent(window);
  155. ::wm::ConvertRectToScreen(window->parent(), &bounds);
  156. return bounds;
  157. }
  158. NOTREACHED() << "The window is not maximzied or fullscreen or pinned. state="
  159. << window_state->GetStateType();
  160. return window->GetBoundsInScreen();
  161. }
  162. } // namespace screen_util
  163. } // namespace ash