screen_ash.cc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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/display/screen_ash.h"
  5. #include "ash/constants/ash_switches.h"
  6. #include "ash/display/window_tree_host_manager.h"
  7. #include "ash/public/cpp/window_finder.h"
  8. #include "ash/root_window_controller.h"
  9. #include "ash/root_window_settings.h"
  10. #include "ash/shelf/shelf_widget.h"
  11. #include "ash/shell.h"
  12. #include "ash/wm/window_util.h"
  13. #include "base/check.h"
  14. #include "base/command_line.h"
  15. #include "base/notreached.h"
  16. #include "ui/aura/client/screen_position_client.h"
  17. #include "ui/aura/env.h"
  18. #include "ui/aura/window.h"
  19. #include "ui/aura/window_event_dispatcher.h"
  20. #include "ui/display/display.h"
  21. #include "ui/display/display_finder.h"
  22. #include "ui/display/manager/display_manager.h"
  23. #include "ui/display/screen.h"
  24. #include "ui/display/types/display_constants.h"
  25. namespace ash {
  26. namespace {
  27. // Intentionally leaked in production.
  28. display::Screen* screen_for_shutdown = nullptr;
  29. display::DisplayManager* GetDisplayManager() {
  30. return Shell::Get()->display_manager();
  31. }
  32. class ScreenForShutdown : public display::Screen {
  33. public:
  34. explicit ScreenForShutdown(display::Screen* screen_ash)
  35. : display_list_(screen_ash->GetAllDisplays()),
  36. primary_display_(screen_ash->GetPrimaryDisplay()) {
  37. SetDisplayForNewWindows(primary_display_.id());
  38. set_shutdown(true);
  39. }
  40. ScreenForShutdown(const ScreenForShutdown&) = delete;
  41. ScreenForShutdown& operator=(const ScreenForShutdown&) = delete;
  42. // display::Screen overrides:
  43. gfx::Point GetCursorScreenPoint() override { return gfx::Point(); }
  44. bool IsWindowUnderCursor(gfx::NativeWindow window) override { return false; }
  45. gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override {
  46. return nullptr;
  47. }
  48. gfx::NativeWindow GetLocalProcessWindowAtPoint(
  49. const gfx::Point& point,
  50. const std::set<gfx::NativeWindow>& ignore) override {
  51. return nullptr;
  52. }
  53. int GetNumDisplays() const override { return display_list_.size(); }
  54. const std::vector<display::Display>& GetAllDisplays() const override {
  55. return display_list_;
  56. }
  57. display::Display GetDisplayNearestWindow(
  58. gfx::NativeView view) const override {
  59. return primary_display_;
  60. }
  61. display::Display GetDisplayNearestPoint(
  62. const gfx::Point& point) const override {
  63. return *display::FindDisplayNearestPoint(display_list_, point);
  64. }
  65. display::Display GetDisplayMatching(
  66. const gfx::Rect& match_rect) const override {
  67. const display::Display* matching =
  68. display::FindDisplayWithBiggestIntersection(display_list_, match_rect);
  69. // Fallback to the primary display if there is no matching display.
  70. return matching ? *matching : GetPrimaryDisplay();
  71. }
  72. display::Display GetPrimaryDisplay() const override {
  73. return primary_display_;
  74. }
  75. void AddObserver(display::DisplayObserver* observer) override {
  76. NOTREACHED() << "Observer should not be added during shutdown";
  77. }
  78. void RemoveObserver(display::DisplayObserver* observer) override {}
  79. private:
  80. const std::vector<display::Display> display_list_;
  81. const display::Display primary_display_;
  82. };
  83. } // namespace
  84. ScreenAsh::ScreenAsh() = default;
  85. ScreenAsh::~ScreenAsh() = default;
  86. gfx::Point ScreenAsh::GetCursorScreenPoint() {
  87. return aura::Env::GetInstance()->last_mouse_location();
  88. }
  89. bool ScreenAsh::IsWindowUnderCursor(gfx::NativeWindow window) {
  90. return window->Contains(GetWindowAtScreenPoint(
  91. display::Screen::GetScreen()->GetCursorScreenPoint()));
  92. }
  93. gfx::NativeWindow ScreenAsh::GetWindowAtScreenPoint(const gfx::Point& point) {
  94. aura::Window* root_window = window_util::GetRootWindowAt(point);
  95. aura::client::ScreenPositionClient* position_client =
  96. aura::client::GetScreenPositionClient(root_window);
  97. gfx::Point local_point = point;
  98. if (position_client)
  99. position_client->ConvertPointFromScreen(root_window, &local_point);
  100. return root_window->GetEventHandlerForPoint(local_point);
  101. }
  102. gfx::NativeWindow ScreenAsh::GetLocalProcessWindowAtPoint(
  103. const gfx::Point& point,
  104. const std::set<gfx::NativeWindow>& ignore) {
  105. return ash::GetTopmostWindowAtPoint(point, ignore);
  106. }
  107. int ScreenAsh::GetNumDisplays() const {
  108. return GetDisplayManager()->GetNumDisplays();
  109. }
  110. const std::vector<display::Display>& ScreenAsh::GetAllDisplays() const {
  111. return GetDisplayManager()->active_display_list();
  112. }
  113. display::Display ScreenAsh::GetDisplayNearestWindow(
  114. gfx::NativeView window) const {
  115. if (!window)
  116. return GetPrimaryDisplay();
  117. const aura::Window* root_window = window->GetRootWindow();
  118. if (!root_window)
  119. return GetPrimaryDisplay();
  120. const RootWindowSettings* rws = GetRootWindowSettings(root_window);
  121. int64_t id = rws->display_id;
  122. // if id is |kInvaildDisplayID|, it's being deleted.
  123. DCHECK(id != display::kInvalidDisplayId);
  124. if (id == display::kInvalidDisplayId)
  125. return GetPrimaryDisplay();
  126. display::DisplayManager* display_manager = GetDisplayManager();
  127. // RootWindow needs Display to determine its device scale factor
  128. // for non desktop display.
  129. display::Display mirroring_display =
  130. display_manager->GetMirroringDisplayById(id);
  131. if (mirroring_display.is_valid())
  132. return mirroring_display;
  133. return display_manager->GetDisplayForId(id);
  134. }
  135. display::Display ScreenAsh::GetDisplayNearestPoint(
  136. const gfx::Point& point) const {
  137. const display::Display& display =
  138. GetDisplayManager()->FindDisplayContainingPoint(point);
  139. if (display.is_valid())
  140. return display;
  141. // Fallback to the display that has the shortest Manhattan distance from
  142. // the |point|. This is correct in the only areas that matter, namely in the
  143. // corners between the physical screens.
  144. return *display::FindDisplayNearestPoint(
  145. GetDisplayManager()->active_only_display_list(), point);
  146. }
  147. display::Display ScreenAsh::GetDisplayMatching(
  148. const gfx::Rect& match_rect) const {
  149. if (match_rect.IsEmpty())
  150. return GetDisplayNearestPoint(match_rect.origin());
  151. const display::Display* matching =
  152. display::FindDisplayWithBiggestIntersection(
  153. GetDisplayManager()->active_only_display_list(), match_rect);
  154. // Fallback to the primary display if there is no matching display.
  155. return matching ? *matching : GetPrimaryDisplay();
  156. }
  157. display::Display ScreenAsh::GetPrimaryDisplay() const {
  158. if (!WindowTreeHostManager::HasValidPrimaryDisplayId()) {
  159. // This should only be allowed temporarily when there are no displays
  160. // available and hence no primary display. In this case we return a default
  161. // display to avoid crashes for display observers trying to get the primary
  162. // display when notified with the removal of the last display.
  163. // https://crbug.com/866714.
  164. DCHECK(
  165. Shell::Get()->window_tree_host_manager()->GetAllRootWindows().empty());
  166. return display::DisplayManager::GetFakePrimaryDisplay();
  167. }
  168. return GetDisplayManager()->GetDisplayForId(
  169. WindowTreeHostManager::GetPrimaryDisplayId());
  170. }
  171. void ScreenAsh::AddObserver(display::DisplayObserver* observer) {
  172. GetDisplayManager()->AddObserver(observer);
  173. }
  174. void ScreenAsh::RemoveObserver(display::DisplayObserver* observer) {
  175. GetDisplayManager()->RemoveObserver(observer);
  176. }
  177. // static
  178. std::unique_ptr<display::DisplayManager> ScreenAsh::CreateDisplayManager() {
  179. auto screen = std::make_unique<ScreenAsh>();
  180. display::Screen* current = display::Screen::GetScreen();
  181. // If there is no native, or the native was for shutdown,
  182. // use ash's screen.
  183. if (!current || current == screen_for_shutdown)
  184. display::Screen::SetScreenInstance(screen.get());
  185. auto manager = std::make_unique<display::DisplayManager>(std::move(screen));
  186. if (base::CommandLine::ForCurrentProcess()->HasSwitch(
  187. switches::kAshEnableTabletMode)) {
  188. manager->set_internal_display_has_accelerometer(true);
  189. }
  190. return manager;
  191. }
  192. // static
  193. void ScreenAsh::CreateScreenForShutdown() {
  194. delete screen_for_shutdown;
  195. screen_for_shutdown = new ScreenForShutdown(display::Screen::GetScreen());
  196. display::Screen::SetScreenInstance(screen_for_shutdown);
  197. }
  198. // static
  199. void ScreenAsh::DeleteScreenForShutdown() {
  200. if (display::Screen::GetScreen() == screen_for_shutdown)
  201. display::Screen::SetScreenInstance(nullptr);
  202. delete screen_for_shutdown;
  203. screen_for_shutdown = nullptr;
  204. }
  205. } // namespace ash