screen_util.cc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. gfx::Rect result =
  47. display::Screen::GetScreen()->GetDisplayNearestWindow(window).work_area();
  48. ::wm::ConvertRectFromScreen(window->parent(), &result);
  49. return result;
  50. }
  51. gfx::Rect GetDisplayWorkAreaBoundsInParentForLockScreen(aura::Window* window) {
  52. gfx::Rect bounds = WorkAreaInsets::ForWindow(window)->user_work_area_bounds();
  53. ::wm::ConvertRectFromScreen(window->parent(), &bounds);
  54. return bounds;
  55. }
  56. gfx::Rect GetDisplayWorkAreaBoundsInParentForActiveDeskContainer(
  57. aura::Window* window) {
  58. aura::Window* root_window = window->GetRootWindow();
  59. return GetDisplayWorkAreaBoundsInParent(
  60. desks_util::GetActiveDeskContainerForRoot(root_window));
  61. }
  62. gfx::Rect GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
  63. aura::Window* window) {
  64. gfx::Rect bounds =
  65. GetDisplayWorkAreaBoundsInParentForActiveDeskContainer(window);
  66. ::wm::ConvertRectToScreen(window->GetRootWindow(), &bounds);
  67. return bounds;
  68. }
  69. gfx::Rect GetDisplayBoundsWithShelf(aura::Window* window) {
  70. if (!Shell::Get()->display_manager()->IsInUnifiedMode()) {
  71. return display::Screen::GetScreen()
  72. ->GetDisplayNearestWindow(window)
  73. .bounds();
  74. }
  75. // In Unified Mode, the display that should contain the shelf depends on the
  76. // current shelf alignment.
  77. const display::Display shelf_display =
  78. Shell::Get()
  79. ->display_configuration_controller()
  80. ->GetPrimaryMirroringDisplayForUnifiedDesktop();
  81. DCHECK_NE(shelf_display.id(), display::kInvalidDisplayId);
  82. gfx::RectF shelf_display_screen_bounds(shelf_display.bounds());
  83. // Transform the bounds back to the unified host's coordinates.
  84. auto inverse_unified_transform =
  85. window->GetRootWindow()->GetHost()->GetInverseRootTransform();
  86. inverse_unified_transform.TransformRect(&shelf_display_screen_bounds);
  87. return gfx::ToEnclosingRect(shelf_display_screen_bounds);
  88. }
  89. gfx::Rect SnapBoundsToDisplayEdge(const gfx::Rect& bounds,
  90. const aura::Window* window) {
  91. display::Display display =
  92. display::Screen::GetScreen()->GetDisplayNearestWindow(
  93. const_cast<aura::Window*>(window));
  94. const float dsf = display.device_scale_factor();
  95. const gfx::Size display_size_in_pixel = display.GetSizeInPixel();
  96. const gfx::Size scaled_size_in_pixel =
  97. gfx::ScaleToFlooredSize(display.size(), dsf);
  98. // Adjusts |bounds| such that the scaled enclosed bounds are atleast as big as
  99. // the scaled enclosing unadjusted bounds.
  100. gfx::Rect snapped_bounds = bounds;
  101. if (scaled_size_in_pixel.width() < display_size_in_pixel.width() &&
  102. display.bounds().right() == bounds.right()) {
  103. snapped_bounds.Inset(gfx::Insets::TLBR(0, 0, 0, -1));
  104. DCHECK_GE(gfx::ScaleToEnclosedRect(snapped_bounds, dsf).right(),
  105. gfx::ScaleToEnclosingRect(bounds, dsf).right());
  106. }
  107. if (scaled_size_in_pixel.height() < display_size_in_pixel.height() &&
  108. display.bounds().bottom() == bounds.bottom()) {
  109. snapped_bounds.Inset(gfx::Insets::TLBR(0, 0, -1, 0));
  110. DCHECK_GE(gfx::ScaleToEnclosedRect(snapped_bounds, dsf).bottom(),
  111. gfx::ScaleToEnclosingRect(bounds, dsf).bottom());
  112. }
  113. return snapped_bounds;
  114. }
  115. gfx::Rect GetIdealBoundsForMaximizedOrFullscreenOrPinnedState(
  116. aura::Window* window) {
  117. auto* window_state = WindowState::Get(window);
  118. if (window_state->IsMaximized()) {
  119. auto* shelf = ash::Shelf::ForWindow(window);
  120. if (shelf->auto_hide_behavior() == ash::ShelfAutoHideBehavior::kAlways) {
  121. gfx::Rect bounds =
  122. ash::screen_util::GetFullscreenWindowBoundsInParent(window);
  123. ::wm::ConvertRectToScreen(window->parent(), &bounds);
  124. return bounds;
  125. }
  126. if (shelf->auto_hide_behavior() ==
  127. ash::ShelfAutoHideBehavior::kAlwaysHidden) {
  128. return display::Screen::GetScreen()
  129. ->GetDisplayNearestWindow(const_cast<aura::Window*>(window))
  130. .work_area();
  131. }
  132. auto work_area =
  133. ash::WorkAreaInsets::ForWindow(window)->ComputeStableWorkArea();
  134. return work_area;
  135. }
  136. if (window_state->IsFullscreen() || window_state->IsPinned()) {
  137. gfx::Rect bounds =
  138. ash::screen_util::GetFullscreenWindowBoundsInParent(window);
  139. ::wm::ConvertRectToScreen(window->parent(), &bounds);
  140. return bounds;
  141. }
  142. NOTREACHED() << "The window is not maximzied or fullscreen or pinned. state="
  143. << window_state->GetStateType();
  144. return window->GetBoundsInScreen();
  145. }
  146. } // namespace screen_util
  147. } // namespace ash