window_tree_host_platform.cc 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // Copyright 2015 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 "ui/aura/window_tree_host_platform.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/observer_list.h"
  9. #include "base/run_loop.h"
  10. #include "base/trace_event/trace_event.h"
  11. #include "build/build_config.h"
  12. #include "ui/aura/client/cursor_client.h"
  13. #include "ui/aura/env.h"
  14. #include "ui/aura/host_frame_rate_throttler.h"
  15. #include "ui/aura/window.h"
  16. #include "ui/aura/window_event_dispatcher.h"
  17. #include "ui/aura/window_tree_host_observer.h"
  18. #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
  19. #include "ui/base/layout.h"
  20. #include "ui/compositor/compositor.h"
  21. #include "ui/display/display.h"
  22. #include "ui/display/screen.h"
  23. #include "ui/events/event.h"
  24. #include "ui/events/keyboard_hook.h"
  25. #include "ui/events/keycodes/dom/dom_code.h"
  26. #include "ui/platform_window/platform_window.h"
  27. #include "ui/platform_window/platform_window_init_properties.h"
  28. #if defined(USE_OZONE)
  29. #include "ui/events/keycodes/dom/dom_keyboard_layout_map.h"
  30. #include "ui/ozone/public/ozone_platform.h"
  31. #endif
  32. #if BUILDFLAG(IS_WIN)
  33. #include "ui/platform_window/win/win_window.h"
  34. #endif
  35. namespace aura {
  36. // static
  37. std::unique_ptr<WindowTreeHost> WindowTreeHost::Create(
  38. ui::PlatformWindowInitProperties properties) {
  39. return std::make_unique<WindowTreeHostPlatform>(
  40. std::move(properties),
  41. std::make_unique<aura::Window>(nullptr, client::WINDOW_TYPE_UNKNOWN));
  42. }
  43. WindowTreeHostPlatform::WindowTreeHostPlatform(
  44. ui::PlatformWindowInitProperties properties,
  45. std::unique_ptr<Window> window)
  46. : WindowTreeHost(std::move(window)) {
  47. size_in_pixels_ = properties.bounds.size();
  48. CreateCompositor(false, false, properties.enable_compositing_based_throttling,
  49. properties.compositor_memory_limit_mb);
  50. CreateAndSetPlatformWindow(std::move(properties));
  51. }
  52. WindowTreeHostPlatform::WindowTreeHostPlatform(std::unique_ptr<Window> window)
  53. : WindowTreeHost(std::move(window)),
  54. widget_(gfx::kNullAcceleratedWidget),
  55. current_cursor_(ui::mojom::CursorType::kNull) {}
  56. void WindowTreeHostPlatform::CreateAndSetPlatformWindow(
  57. ui::PlatformWindowInitProperties properties) {
  58. // Cache initial size used to create |platform_window_| so that it does not
  59. // end up propagating unneeded bounds change event when it is first notified
  60. // through OnBoundsChanged, which may lead to unneeded re-layouts, etc.
  61. size_in_pixels_ = properties.bounds.size();
  62. #if defined(USE_OZONE)
  63. platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow(
  64. this, std::move(properties));
  65. #elif BUILDFLAG(IS_WIN)
  66. platform_window_ = std::make_unique<ui::WinWindow>(this, properties.bounds);
  67. #else
  68. NOTIMPLEMENTED();
  69. #endif
  70. }
  71. void WindowTreeHostPlatform::SetPlatformWindow(
  72. std::unique_ptr<ui::PlatformWindow> window) {
  73. platform_window_ = std::move(window);
  74. }
  75. WindowTreeHostPlatform::~WindowTreeHostPlatform() {
  76. DestroyCompositor();
  77. DestroyDispatcher();
  78. // |platform_window_| may not exist yet.
  79. if (platform_window_)
  80. platform_window_->Close();
  81. }
  82. ui::EventSource* WindowTreeHostPlatform::GetEventSource() {
  83. return this;
  84. }
  85. gfx::AcceleratedWidget WindowTreeHostPlatform::GetAcceleratedWidget() {
  86. return widget_;
  87. }
  88. void WindowTreeHostPlatform::ShowImpl() {
  89. platform_window_->Show();
  90. }
  91. void WindowTreeHostPlatform::HideImpl() {
  92. platform_window_->Hide();
  93. }
  94. gfx::Rect WindowTreeHostPlatform::GetBoundsInPixels() const {
  95. return platform_window_->GetBoundsInPixels();
  96. }
  97. void WindowTreeHostPlatform::SetBoundsInPixels(const gfx::Rect& bounds) {
  98. platform_window_->SetBoundsInPixels(bounds);
  99. }
  100. void WindowTreeHostPlatform::SetCapture() {
  101. platform_window_->SetCapture();
  102. }
  103. void WindowTreeHostPlatform::ReleaseCapture() {
  104. platform_window_->ReleaseCapture();
  105. }
  106. gfx::Point WindowTreeHostPlatform::GetLocationOnScreenInPixels() const {
  107. return platform_window_->GetBoundsInPixels().origin();
  108. }
  109. bool WindowTreeHostPlatform::CaptureSystemKeyEventsImpl(
  110. absl::optional<base::flat_set<ui::DomCode>> dom_codes) {
  111. // Only one KeyboardHook should be active at a time, otherwise there will be
  112. // problems with event routing (i.e. which Hook takes precedence) and
  113. // destruction ordering.
  114. DCHECK(!keyboard_hook_);
  115. keyboard_hook_ = ui::KeyboardHook::CreateModifierKeyboardHook(
  116. std::move(dom_codes), GetAcceleratedWidget(),
  117. base::BindRepeating(
  118. [](ui::PlatformWindowDelegate* delegate, ui::KeyEvent* event) {
  119. delegate->DispatchEvent(event);
  120. },
  121. base::Unretained(this)));
  122. return keyboard_hook_ != nullptr;
  123. }
  124. void WindowTreeHostPlatform::ReleaseSystemKeyEventCapture() {
  125. keyboard_hook_.reset();
  126. }
  127. bool WindowTreeHostPlatform::IsKeyLocked(ui::DomCode dom_code) {
  128. return keyboard_hook_ && keyboard_hook_->IsKeyLocked(dom_code);
  129. }
  130. base::flat_map<std::string, std::string>
  131. WindowTreeHostPlatform::GetKeyboardLayoutMap() {
  132. #if defined(USE_OZONE)
  133. return ui::GenerateDomKeyboardLayoutMap();
  134. #else
  135. NOTIMPLEMENTED();
  136. return {};
  137. #endif
  138. }
  139. void WindowTreeHostPlatform::SetCursorNative(gfx::NativeCursor cursor) {
  140. if (cursor == current_cursor_)
  141. return;
  142. current_cursor_ = cursor;
  143. platform_window_->SetCursor(cursor.platform());
  144. }
  145. void WindowTreeHostPlatform::MoveCursorToScreenLocationInPixels(
  146. const gfx::Point& location_in_pixels) {
  147. platform_window_->MoveCursorTo(location_in_pixels);
  148. }
  149. void WindowTreeHostPlatform::OnCursorVisibilityChangedNative(bool show) {
  150. NOTIMPLEMENTED_LOG_ONCE();
  151. }
  152. void WindowTreeHostPlatform::LockMouse(Window* window) {
  153. window->SetCapture();
  154. WindowTreeHost::LockMouse(window);
  155. }
  156. void WindowTreeHostPlatform::OnBoundsChanged(const BoundsChange& change) {
  157. // It's possible this function may be called recursively. Only notify
  158. // observers on initial entry. This way observers can safely assume that
  159. // OnHostDidProcessBoundsChange() is called when all bounds changes have
  160. // completed.
  161. if (++on_bounds_changed_recursion_depth_ == 1) {
  162. for (WindowTreeHostObserver& observer : observers())
  163. observer.OnHostWillProcessBoundsChange(this);
  164. }
  165. float current_scale = compositor()->device_scale_factor();
  166. float new_scale = ui::GetScaleFactorForNativeView(window());
  167. auto weak_ref = GetWeakPtr();
  168. auto new_size = GetBoundsInPixels().size();
  169. bool size_changed = size_in_pixels_ != new_size;
  170. size_in_pixels_ = new_size;
  171. if (change.origin_changed) {
  172. OnHostMovedInPixels();
  173. // Changing the bounds may destroy this.
  174. if (!weak_ref)
  175. return;
  176. }
  177. if (size_changed || current_scale != new_scale) {
  178. OnHostResizedInPixels(new_size);
  179. // Changing the size may destroy this.
  180. if (!weak_ref)
  181. return;
  182. }
  183. DCHECK_GT(on_bounds_changed_recursion_depth_, 0);
  184. if (--on_bounds_changed_recursion_depth_ == 0) {
  185. for (WindowTreeHostObserver& observer : observers())
  186. observer.OnHostDidProcessBoundsChange(this);
  187. }
  188. }
  189. void WindowTreeHostPlatform::OnDamageRect(const gfx::Rect& damage_rect) {
  190. compositor()->ScheduleRedrawRect(damage_rect);
  191. }
  192. void WindowTreeHostPlatform::DispatchEvent(ui::Event* event) {
  193. TRACE_EVENT0("input", "WindowTreeHostPlatform::DispatchEvent");
  194. ui::EventDispatchDetails details = SendEventToSink(event);
  195. if (details.dispatcher_destroyed)
  196. event->SetHandled();
  197. }
  198. void WindowTreeHostPlatform::OnCloseRequest() {
  199. OnHostCloseRequested();
  200. }
  201. void WindowTreeHostPlatform::OnClosed() {}
  202. void WindowTreeHostPlatform::OnWindowStateChanged(
  203. ui::PlatformWindowState old_state,
  204. ui::PlatformWindowState new_state) {}
  205. void WindowTreeHostPlatform::OnLostCapture() {
  206. OnHostLostWindowCapture();
  207. }
  208. void WindowTreeHostPlatform::OnAcceleratedWidgetAvailable(
  209. gfx::AcceleratedWidget widget) {
  210. widget_ = widget;
  211. // This may be called before the Compositor has been created.
  212. if (compositor())
  213. WindowTreeHost::OnAcceleratedWidgetAvailable();
  214. }
  215. void WindowTreeHostPlatform::OnWillDestroyAcceleratedWidget() {}
  216. void WindowTreeHostPlatform::OnAcceleratedWidgetDestroyed() {
  217. gfx::AcceleratedWidget widget = compositor()->ReleaseAcceleratedWidget();
  218. DCHECK_EQ(widget, widget_);
  219. widget_ = gfx::kNullAcceleratedWidget;
  220. }
  221. void WindowTreeHostPlatform::OnActivationChanged(bool active) {}
  222. void WindowTreeHostPlatform::OnMouseEnter() {
  223. client::CursorClient* cursor_client = client::GetCursorClient(window());
  224. if (cursor_client) {
  225. auto display =
  226. display::Screen::GetScreen()->GetDisplayNearestWindow(window());
  227. DCHECK(display.is_valid());
  228. cursor_client->SetDisplay(display);
  229. }
  230. }
  231. void WindowTreeHostPlatform::OnOcclusionStateChanged(
  232. ui::PlatformWindowOcclusionState occlusion_state) {
  233. auto aura_occlusion_state = Window::OcclusionState::UNKNOWN;
  234. switch (occlusion_state) {
  235. case ui::PlatformWindowOcclusionState::kUnknown:
  236. aura_occlusion_state = Window::OcclusionState::UNKNOWN;
  237. break;
  238. case ui::PlatformWindowOcclusionState::kVisible:
  239. aura_occlusion_state = Window::OcclusionState::VISIBLE;
  240. break;
  241. case ui::PlatformWindowOcclusionState::kOccluded:
  242. aura_occlusion_state = Window::OcclusionState::OCCLUDED;
  243. break;
  244. case ui::PlatformWindowOcclusionState::kHidden:
  245. aura_occlusion_state = Window::OcclusionState::HIDDEN;
  246. break;
  247. }
  248. SetNativeWindowOcclusionState(aura_occlusion_state, {});
  249. }
  250. void WindowTreeHostPlatform::SetFrameRateThrottleEnabled(bool enabled) {
  251. if (enabled)
  252. HostFrameRateThrottler::GetInstance().AddHost(this);
  253. else
  254. HostFrameRateThrottler::GetInstance().RemoveHost(this);
  255. }
  256. } // namespace aura