application_bridge.mm 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Copyright 2018 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 "components/remote_cocoa/app_shim/application_bridge.h"
  5. #include <tuple>
  6. #include "base/bind.h"
  7. #include "base/no_destructor.h"
  8. #include "components/remote_cocoa/app_shim/alert.h"
  9. #include "components/remote_cocoa/app_shim/color_panel_bridge.h"
  10. #include "components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h"
  11. #include "components/remote_cocoa/app_shim/native_widget_ns_window_host_helper.h"
  12. #include "mojo/public/cpp/bindings/associated_remote.h"
  13. #include "mojo/public/cpp/bindings/self_owned_receiver.h"
  14. #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
  15. #include "ui/base/cocoa/remote_accessibility_api.h"
  16. namespace remote_cocoa {
  17. namespace {
  18. class NativeWidgetBridgeOwner : public NativeWidgetNSWindowHostHelper {
  19. public:
  20. NativeWidgetBridgeOwner(
  21. uint64_t bridge_id,
  22. mojo::PendingAssociatedReceiver<mojom::NativeWidgetNSWindow>
  23. bridge_receiver,
  24. mojo::PendingAssociatedRemote<mojom::NativeWidgetNSWindowHost>
  25. host_remote,
  26. mojo::PendingAssociatedRemote<mojom::TextInputHost>
  27. text_input_host_remote) {
  28. host_remote_.Bind(std::move(host_remote),
  29. ui::WindowResizeHelperMac::Get()->task_runner());
  30. text_input_host_remote_.Bind(
  31. std::move(text_input_host_remote),
  32. ui::WindowResizeHelperMac::Get()->task_runner());
  33. bridge_ = std::make_unique<NativeWidgetNSWindowBridge>(
  34. bridge_id, host_remote_.get(), this, text_input_host_remote_.get());
  35. bridge_->BindReceiver(
  36. std::move(bridge_receiver),
  37. base::BindOnce(&NativeWidgetBridgeOwner::OnMojoDisconnect,
  38. base::Unretained(this)));
  39. }
  40. private:
  41. ~NativeWidgetBridgeOwner() override {}
  42. void OnMojoDisconnect() { delete this; }
  43. // NativeWidgetNSWindowHostHelper:
  44. id GetNativeViewAccessible() override {
  45. if (!remote_accessibility_element_) {
  46. int64_t browser_pid = 0;
  47. std::vector<uint8_t> element_token;
  48. host_remote_->GetRootViewAccessibilityToken(&browser_pid, &element_token);
  49. [NSAccessibilityRemoteUIElement
  50. registerRemoteUIProcessIdentifier:browser_pid];
  51. remote_accessibility_element_ =
  52. ui::RemoteAccessibility::GetRemoteElementFromToken(element_token);
  53. }
  54. return remote_accessibility_element_.get();
  55. }
  56. void DispatchKeyEvent(ui::KeyEvent* event) override {
  57. bool event_handled = false;
  58. host_remote_->DispatchKeyEventRemote(std::make_unique<ui::KeyEvent>(*event),
  59. &event_handled);
  60. if (event_handled)
  61. event->SetHandled();
  62. }
  63. bool DispatchKeyEventToMenuController(ui::KeyEvent* event) override {
  64. bool event_swallowed = false;
  65. bool event_handled = false;
  66. host_remote_->DispatchKeyEventToMenuControllerRemote(
  67. std::make_unique<ui::KeyEvent>(*event), &event_swallowed,
  68. &event_handled);
  69. if (event_handled)
  70. event->SetHandled();
  71. return event_swallowed;
  72. }
  73. void GetWordAt(const gfx::Point& location_in_content,
  74. bool* found_word,
  75. gfx::DecoratedText* decorated_word,
  76. gfx::Point* baseline_point) override {
  77. *found_word = false;
  78. }
  79. remote_cocoa::DragDropClient* GetDragDropClient() override {
  80. // Drag-drop only doesn't work across mojo yet.
  81. return nullptr;
  82. }
  83. ui::TextInputClient* GetTextInputClient() override {
  84. // Text input doesn't work across mojo yet.
  85. return nullptr;
  86. }
  87. bool MustPostTaskToRunModalSheetAnimation() const override { return true; }
  88. mojo::AssociatedRemote<mojom::NativeWidgetNSWindowHost> host_remote_;
  89. mojo::AssociatedRemote<mojom::TextInputHost> text_input_host_remote_;
  90. std::unique_ptr<NativeWidgetNSWindowBridge> bridge_;
  91. base::scoped_nsobject<NSAccessibilityRemoteUIElement>
  92. remote_accessibility_element_;
  93. };
  94. } // namespace
  95. // static
  96. ApplicationBridge* ApplicationBridge::Get() {
  97. static base::NoDestructor<ApplicationBridge> application_bridge;
  98. return application_bridge.get();
  99. }
  100. void ApplicationBridge::BindReceiver(
  101. mojo::PendingAssociatedReceiver<mojom::Application> receiver) {
  102. receiver_.Bind(std::move(receiver),
  103. ui::WindowResizeHelperMac::Get()->task_runner());
  104. }
  105. void ApplicationBridge::SetContentNSViewCreateCallbacks(
  106. RenderWidgetHostNSViewCreateCallback render_widget_host_create_callback,
  107. WebContentsNSViewCreateCallback web_conents_create_callback) {
  108. render_widget_host_create_callback_ = render_widget_host_create_callback;
  109. web_conents_create_callback_ = web_conents_create_callback;
  110. }
  111. void ApplicationBridge::CreateAlert(
  112. mojo::PendingReceiver<mojom::AlertBridge> bridge_receiver) {
  113. // The resulting object manages its own lifetime.
  114. std::ignore = new AlertBridge(std::move(bridge_receiver));
  115. }
  116. void ApplicationBridge::ShowColorPanel(
  117. mojo::PendingReceiver<mojom::ColorPanel> receiver,
  118. mojo::PendingRemote<mojom::ColorPanelHost> host) {
  119. mojo::MakeSelfOwnedReceiver(
  120. std::make_unique<ColorPanelBridge>(std::move(host)), std::move(receiver));
  121. }
  122. void ApplicationBridge::CreateNativeWidgetNSWindow(
  123. uint64_t bridge_id,
  124. mojo::PendingAssociatedReceiver<mojom::NativeWidgetNSWindow>
  125. bridge_receiver,
  126. mojo::PendingAssociatedRemote<mojom::NativeWidgetNSWindowHost> host,
  127. mojo::PendingAssociatedRemote<mojom::TextInputHost> text_input_host) {
  128. // The resulting object will be destroyed when its message pipe is closed.
  129. std::ignore =
  130. new NativeWidgetBridgeOwner(bridge_id, std::move(bridge_receiver),
  131. std::move(host), std::move(text_input_host));
  132. }
  133. void ApplicationBridge::CreateRenderWidgetHostNSView(
  134. uint64_t view_id,
  135. mojo::PendingAssociatedRemote<mojom::StubInterface> host,
  136. mojo::PendingAssociatedReceiver<mojom::StubInterface> view_receiver) {
  137. if (!render_widget_host_create_callback_)
  138. return;
  139. render_widget_host_create_callback_.Run(view_id, host.PassHandle(),
  140. view_receiver.PassHandle());
  141. }
  142. void ApplicationBridge::CreateWebContentsNSView(
  143. uint64_t view_id,
  144. mojo::PendingAssociatedRemote<mojom::StubInterface> host,
  145. mojo::PendingAssociatedReceiver<mojom::StubInterface> view_receiver) {
  146. if (!web_conents_create_callback_)
  147. return;
  148. web_conents_create_callback_.Run(view_id, host.PassHandle(),
  149. view_receiver.PassHandle());
  150. }
  151. void ApplicationBridge::ForwardCutCopyPaste(
  152. mojom::CutCopyPasteCommand command) {
  153. ForwardCutCopyPasteToNSApp(command);
  154. }
  155. // static
  156. void ApplicationBridge::ForwardCutCopyPasteToNSApp(
  157. mojom::CutCopyPasteCommand command) {
  158. switch (command) {
  159. case mojom::CutCopyPasteCommand::kCut:
  160. [NSApp sendAction:@selector(cut:) to:nil from:nil];
  161. break;
  162. case mojom::CutCopyPasteCommand::kCopy:
  163. [NSApp sendAction:@selector(copy:) to:nil from:nil];
  164. break;
  165. case mojom::CutCopyPasteCommand::kPaste:
  166. [NSApp sendAction:@selector(paste:) to:nil from:nil];
  167. break;
  168. }
  169. }
  170. ApplicationBridge::ApplicationBridge() = default;
  171. ApplicationBridge::~ApplicationBridge() = default;
  172. } // namespace remote_cocoa