Commit 2f9fe770 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

RemoteMacViews: Add NSView handles

Add integer handles for NSViews that may be created in the app shim
process. This includes the BridgedNativeWidget content view and soon
will include the WebContentsView. A handle is not added for
RenderWidgetHostView because there are no planned methods that would
use it.

These handles will be needed for methods that require interactions
between NSViews created by different interfaces. Add as an example the
method RenderWidgetHostNSViewBridge::SetParentWebContentsNSView. This
will allow constructing the NSView hierarchy in the app shim process:
- BridgedNativeWidget
  - WebContentsView (coming in subsequent patches)
    - RenderWidgetHostView

Bug: 821651
Change-Id: I225eb03f122baa9aea770d28e98a44c938943434
Reviewed-on: https://chromium-review.googlesource.com/1253094
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarSidney San Martín <sdy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595746}
parent 03333c5c
...@@ -49,6 +49,7 @@ class RenderWidgetHostNSViewBridgeLocal ...@@ -49,6 +49,7 @@ class RenderWidgetHostNSViewBridgeLocal
// mojom::RenderWidgetHostNSViewBridge implementation. // mojom::RenderWidgetHostNSViewBridge implementation.
void InitAsPopup(const gfx::Rect& content_rect) override; void InitAsPopup(const gfx::Rect& content_rect) override;
void SetParentWebContentsNSView(uint64_t parent_ns_view_id) override;
void DisableDisplay() override; void DisableDisplay() override;
void MakeFirstResponder() override; void MakeFirstResponder() override;
void SetBounds(const gfx::Rect& rect) override; void SetBounds(const gfx::Rect& rect) override;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "content/common/cursors/webcursor.h" #include "content/common/cursors/webcursor.h"
#import "skia/ext/skia_utils_mac.h" #import "skia/ext/skia_utils_mac.h"
#import "ui/base/cocoa/animation_utils.h" #import "ui/base/cocoa/animation_utils.h"
#include "ui/base/cocoa/ns_view_ids.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/dom_code.h"
#include "ui/gfx/mac/coordinate_conversion.h" #include "ui/gfx/mac/coordinate_conversion.h"
...@@ -82,6 +83,18 @@ void RenderWidgetHostNSViewBridgeLocal::InitAsPopup( ...@@ -82,6 +83,18 @@ void RenderWidgetHostNSViewBridgeLocal::InitAsPopup(
popup_window_ = std::make_unique<PopupWindowMac>(content_rect, cocoa_view_); popup_window_ = std::make_unique<PopupWindowMac>(content_rect, cocoa_view_);
} }
void RenderWidgetHostNSViewBridgeLocal::SetParentWebContentsNSView(
uint64_t parent_ns_view_id) {
NSView* parent_ns_view = ui::NSViewIds::GetNSView(parent_ns_view_id);
// If the browser passed an invalid handle, then there is no recovery.
CHECK(parent_ns_view);
// Set the frame and autoresizing mask of the RenderWidgetHostViewCocoa as is
// done by WebContentsViewMac.
[cocoa_view_ setFrame:[parent_ns_view bounds]];
[cocoa_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[parent_ns_view addSubview:cocoa_view_];
}
void RenderWidgetHostNSViewBridgeLocal::MakeFirstResponder() { void RenderWidgetHostNSViewBridgeLocal::MakeFirstResponder() {
[[cocoa_view_ window] makeFirstResponder:cocoa_view_]; [[cocoa_view_ window] makeFirstResponder:cocoa_view_];
} }
......
...@@ -24,6 +24,10 @@ interface RenderWidgetHostNSViewBridge { ...@@ -24,6 +24,10 @@ interface RenderWidgetHostNSViewBridge {
// create its own NSWindow. // create its own NSWindow.
InitAsPopup(gfx.mojom.Rect content_rect); InitAsPopup(gfx.mojom.Rect content_rect);
// Set this to be a child NSView of the NSView mapped to by
// |parent_ns_view_id|.
SetParentWebContentsNSView(uint64 parent_ns_view_id);
// Disable displaying any content (including the background color). This is // Disable displaying any content (including the background color). This is
// to be called on views that are to be displayed via a parent ui::Compositor. // to be called on views that are to be displayed via a parent ui::Compositor.
DisableDisplay(); DisableDisplay();
......
...@@ -122,6 +122,8 @@ jumbo_component("base") { ...@@ -122,6 +122,8 @@ jumbo_component("base") {
"cocoa/menu_controller.mm", "cocoa/menu_controller.mm",
"cocoa/nib_loading.h", "cocoa/nib_loading.h",
"cocoa/nib_loading.mm", "cocoa/nib_loading.mm",
"cocoa/ns_view_ids.h",
"cocoa/ns_view_ids.mm",
"cocoa/nsgraphics_context_additions.h", "cocoa/nsgraphics_context_additions.h",
"cocoa/nsgraphics_context_additions.mm", "cocoa/nsgraphics_context_additions.mm",
"cocoa/nsview_additions.h", "cocoa/nsview_additions.h",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_BASE_COCOA_NS_VIEW_IDS_H_
#define UI_BASE_COCOA_NS_VIEW_IDS_H_
#include <stdint.h>
#include "base/macros.h"
#include "ui/base/ui_base_export.h"
@class NSView;
namespace ui {
// A class used to manage NSViews across processes.
// - NSViews that may be instantiated in another process are assigned an id in
// the browser process.
// - Instantiating a ScopedNSViewIdMapping in the process where the NSView is
// created will make NSViewIds::GetNSView return the specified NSView.
// - This mechanism is used by mojo methods to refer to NSViews across
// interfaces (in particular, to specify parent NSViews).
class UI_BASE_EXPORT NSViewIds {
public:
// Get a new id to use with a new NSView. This is to only be called in the
// browser process.
static uint64_t GetNewId();
// Return an NSView given its id. This is to be called in an app shim process.
static NSView* GetNSView(uint64_t ns_view_id);
};
// A scoped mapping from |ns_view_id| to |view|. While this object exists,
// NSViewIds::GetNSView will return |view| when queried with |ns_view_id|. This
// is to be instantiated in the app shim process.
class UI_BASE_EXPORT ScopedNSViewIdMapping {
public:
ScopedNSViewIdMapping(uint64_t ns_view_id, NSView* view);
~ScopedNSViewIdMapping();
private:
const uint64_t ns_view_id_;
DISALLOW_COPY_AND_ASSIGN(ScopedNSViewIdMapping);
};
} // namespace ui
#endif // UI_BASE_COCOA_NS_VIEW_IDS_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/base/cocoa/ns_view_ids.h"
#import <Cocoa/Cocoa.h>
#include <map>
#include <utility>
#include "base/logging.h"
#include "base/no_destructor.h"
namespace ui {
std::map<uint64_t, NSView*>& GetNSViewIdMap() {
static base::NoDestructor<std::map<uint64_t, NSView*>> instance;
return *instance;
}
// static
uint64_t NSViewIds::GetNewId() {
static uint64_t next_id = 1;
return next_id++;
}
// static
NSView* NSViewIds::GetNSView(uint64_t ns_view_id) {
auto& view_map = GetNSViewIdMap();
auto found = view_map.find(ns_view_id);
if (found == view_map.end())
return nil;
return found->second;
}
ScopedNSViewIdMapping::ScopedNSViewIdMapping(uint64_t ns_view_id, NSView* view)
: ns_view_id_(ns_view_id) {
auto result = GetNSViewIdMap().insert(std::make_pair(ns_view_id, view));
DCHECK(result.second);
}
ScopedNSViewIdMapping::~ScopedNSViewIdMapping() {
auto& view_map = GetNSViewIdMap();
auto found = view_map.find(ns_view_id_);
DCHECK(found != view_map.end());
view_map.erase(found);
}
} // namespace ui
...@@ -60,7 +60,7 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl ...@@ -60,7 +60,7 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
// potentially in another. // potentially in another.
static BridgedNativeWidgetHostImpl* GetFromId( static BridgedNativeWidgetHostImpl* GetFromId(
uint64_t bridged_native_widget_id); uint64_t bridged_native_widget_id);
uint64_t bridged_native_widget_id() const { return id_; } uint64_t bridged_native_widget_id() const { return widget_id_; }
// Creates one side of the bridge. |parent| must not be NULL. // Creates one side of the bridge. |parent| must not be NULL.
explicit BridgedNativeWidgetHostImpl(NativeWidgetMac* parent); explicit BridgedNativeWidgetHostImpl(NativeWidgetMac* parent);
...@@ -127,6 +127,9 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl ...@@ -127,6 +127,9 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
// Set the root view (set during initialization and un-set during teardown). // Set the root view (set during initialization and un-set during teardown).
void SetRootView(views::View* root_view); void SetRootView(views::View* root_view);
// Return the id through which the NSView for |root_view_| may be looked up.
uint64_t GetRootViewNSViewId() const { return root_view_id_; }
// Initialize the ui::Compositor and ui::Layer. // Initialize the ui::Compositor and ui::Layer.
void CreateCompositor(const Widget::InitParams& params); void CreateCompositor(const Widget::InitParams& params);
...@@ -293,7 +296,8 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl ...@@ -293,7 +296,8 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
// ui::AcceleratedWidgetMacNSView: // ui::AcceleratedWidgetMacNSView:
void AcceleratedWidgetCALayerParamsUpdated() override; void AcceleratedWidgetCALayerParamsUpdated() override;
const uint64_t id_; // The id that this bridge may be looked up from.
const uint64_t widget_id_;
views::NativeWidgetMac* const native_widget_mac_; // Weak. Owns |this_|. views::NativeWidgetMac* const native_widget_mac_; // Weak. Owns |this_|.
// The factory that was used to create |bridge_ptr_|. // The factory that was used to create |bridge_ptr_|.
...@@ -301,6 +305,8 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl ...@@ -301,6 +305,8 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
Widget::InitParams::Type widget_type_ = Widget::InitParams::TYPE_WINDOW; Widget::InitParams::Type widget_type_ = Widget::InitParams::TYPE_WINDOW;
// The id that may be used to look up the NSView for |root_view_|.
const uint64_t root_view_id_;
views::View* root_view_ = nullptr; // Weak. Owned by |native_widget_mac_|. views::View* root_view_ = nullptr; // Weak. Owned by |native_widget_mac_|.
std::unique_ptr<DragDropClientMac> drag_drop_client_; std::unique_ptr<DragDropClientMac> drag_drop_client_;
......
...@@ -77,25 +77,25 @@ BridgedNativeWidgetHostImpl* BridgedNativeWidgetHostImpl::GetFromId( ...@@ -77,25 +77,25 @@ BridgedNativeWidgetHostImpl* BridgedNativeWidgetHostImpl::GetFromId(
BridgedNativeWidgetHostImpl::BridgedNativeWidgetHostImpl( BridgedNativeWidgetHostImpl::BridgedNativeWidgetHostImpl(
NativeWidgetMac* parent) NativeWidgetMac* parent)
: id_(++g_last_bridged_native_widget_id), : widget_id_(++g_last_bridged_native_widget_id),
native_widget_mac_(parent), native_widget_mac_(parent),
root_view_id_(ui::NSViewIds::GetNewId()),
host_mojo_binding_(this) { host_mojo_binding_(this) {
DCHECK(GetIdToWidgetHostImplMap().find(id_) == DCHECK(GetIdToWidgetHostImplMap().find(widget_id_) ==
GetIdToWidgetHostImplMap().end()); GetIdToWidgetHostImplMap().end());
GetIdToWidgetHostImplMap().insert(std::make_pair(id_, this)); GetIdToWidgetHostImplMap().insert(std::make_pair(widget_id_, this));
GetIdToWidgetHostImplMap().insert(std::make_pair(id_, this));
DCHECK(parent); DCHECK(parent);
} }
BridgedNativeWidgetHostImpl::~BridgedNativeWidgetHostImpl() { BridgedNativeWidgetHostImpl::~BridgedNativeWidgetHostImpl() {
if (bridge_factory_host_) { if (bridge_factory_host_) {
bridge_factory_host_->GetFactory()->DestroyBridge(id_); bridge_factory_host_->GetFactory()->DestroyBridge(widget_id_);
bridge_factory_host_->RemoveObserver(this); bridge_factory_host_->RemoveObserver(this);
bridge_factory_host_ = nullptr; bridge_factory_host_ = nullptr;
} }
// Ensure that |this| cannot be reached by its id while it is being destroyed. // Ensure that |this| cannot be reached by its id while it is being destroyed.
auto found = GetIdToWidgetHostImplMap().find(id_); auto found = GetIdToWidgetHostImplMap().find(widget_id_);
DCHECK(found != GetIdToWidgetHostImplMap().end()); DCHECK(found != GetIdToWidgetHostImplMap().end());
DCHECK_EQ(found->second, this); DCHECK_EQ(found->second, this);
GetIdToWidgetHostImplMap().erase(found); GetIdToWidgetHostImplMap().erase(found);
...@@ -126,7 +126,8 @@ void BridgedNativeWidgetHostImpl::CreateLocalBridge( ...@@ -126,7 +126,8 @@ void BridgedNativeWidgetHostImpl::CreateLocalBridge(
base::scoped_nsobject<NativeWidgetMacNSWindow> window, base::scoped_nsobject<NativeWidgetMacNSWindow> window,
NSView* parent) { NSView* parent) {
local_window_ = window; local_window_ = window;
bridge_impl_ = std::make_unique<BridgedNativeWidgetImpl>(id_, this, this); bridge_impl_ =
std::make_unique<BridgedNativeWidgetImpl>(widget_id_, this, this);
bridge_impl_->SetWindow(window); bridge_impl_->SetWindow(window);
if (parent) if (parent)
bridge_impl_->SetParent(parent); bridge_impl_->SetParent(parent);
...@@ -143,14 +144,14 @@ void BridgedNativeWidgetHostImpl::CreateRemoteBridge( ...@@ -143,14 +144,14 @@ void BridgedNativeWidgetHostImpl::CreateRemoteBridge(
// other process. // other process.
local_window_ = local_window_ =
BridgedNativeWidgetImpl::CreateNSWindow(window_create_params.get()); BridgedNativeWidgetImpl::CreateNSWindow(window_create_params.get());
[local_window_ setBridgedNativeWidgetId:id_]; [local_window_ setBridgedNativeWidgetId:widget_id_];
// Initialize |bridge_ptr_| to point to a bridge created by |factory|. // Initialize |bridge_ptr_| to point to a bridge created by |factory|.
views_bridge_mac::mojom::BridgedNativeWidgetHostPtr host_ptr; views_bridge_mac::mojom::BridgedNativeWidgetHostPtr host_ptr;
host_mojo_binding_.Bind(mojo::MakeRequest(&host_ptr), host_mojo_binding_.Bind(mojo::MakeRequest(&host_ptr),
ui::WindowResizeHelperMac::Get()->task_runner()); ui::WindowResizeHelperMac::Get()->task_runner());
bridge_factory_host_->GetFactory()->CreateBridge( bridge_factory_host_->GetFactory()->CreateBridge(
id_, mojo::MakeRequest(&bridge_ptr_), std::move(host_ptr)); widget_id_, mojo::MakeRequest(&bridge_ptr_), std::move(host_ptr));
// Create the window in its process, and attach it to its parent window. // Create the window in its process, and attach it to its parent window.
bridge()->CreateWindow(std::move(window_create_params), parent_bridge_id); bridge()->CreateWindow(std::move(window_create_params), parent_bridge_id);
......
...@@ -618,7 +618,8 @@ void BridgedNativeWidgetTest::SetUp() { ...@@ -618,7 +618,8 @@ void BridgedNativeWidgetTest::SetUp() {
// The delegate should exist before setting the root view. // The delegate should exist before setting the root view.
EXPECT_TRUE([window delegate]); EXPECT_TRUE([window delegate]);
bridge_host()->SetRootView(view_.get()); bridge_host()->SetRootView(view_.get());
bridge()->CreateContentView(view_->bounds()); bridge()->CreateContentView(bridge_host()->GetRootViewNSViewId(),
view_->bounds());
ns_view_ = bridge()->ns_view(); ns_view_ = bridge()->ns_view();
// Pretend it has been shown via NativeWidgetMac::Show(). // Pretend it has been shown via NativeWidgetMac::Show().
......
...@@ -144,7 +144,8 @@ void NativeWidgetMac::InitNativeWidget(const Widget::InitParams& params) { ...@@ -144,7 +144,8 @@ void NativeWidgetMac::InitNativeWidget(const Widget::InitParams& params) {
DCHECK(GetWidget()->GetRootView()); DCHECK(GetWidget()->GetRootView());
bridge_host_->SetRootView(GetWidget()->GetRootView()); bridge_host_->SetRootView(GetWidget()->GetRootView());
bridge()->CreateContentView(GetWidget()->GetRootView()->bounds()); bridge()->CreateContentView(bridge_host_->GetRootViewNSViewId(),
GetWidget()->GetRootView()->bounds());
if (auto* focus_manager = GetWidget()->GetFocusManager()) { if (auto* focus_manager = GetWidget()->GetFocusManager()) {
bridge()->MakeFirstResponder(); bridge()->MakeFirstResponder();
bridge_host_->SetFocusManager(focus_manager); bridge_host_->SetFocusManager(focus_manager);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "ui/accelerated_widget_mac/ca_transaction_observer.h" #include "ui/accelerated_widget_mac/ca_transaction_observer.h"
#include "ui/accelerated_widget_mac/display_ca_layer_tree.h" #include "ui/accelerated_widget_mac/display_ca_layer_tree.h"
#include "ui/base/cocoa/ns_view_ids.h"
#include "ui/base/ime/text_input_client.h" #include "ui/base/ime/text_input_client.h"
#include "ui/display/display_observer.h" #include "ui/display/display_observer.h"
#include "ui/views/views_export.h" #include "ui/views/views_export.h"
...@@ -205,7 +206,7 @@ class VIEWS_EXPORT BridgedNativeWidgetImpl ...@@ -205,7 +206,7 @@ class VIEWS_EXPORT BridgedNativeWidgetImpl
void InitWindow(views_bridge_mac::mojom::BridgedNativeWidgetInitParamsPtr void InitWindow(views_bridge_mac::mojom::BridgedNativeWidgetInitParamsPtr
params) override; params) override;
void InitCompositorView() override; void InitCompositorView() override;
void CreateContentView(const gfx::Rect& bounds) override; void CreateContentView(uint64_t ns_view_id, const gfx::Rect& bounds) override;
void DestroyContentView() override; void DestroyContentView() override;
void CloseWindow() override; void CloseWindow() override;
void CloseWindowNow() override; void CloseWindowNow() override;
...@@ -284,6 +285,7 @@ class VIEWS_EXPORT BridgedNativeWidgetImpl ...@@ -284,6 +285,7 @@ class VIEWS_EXPORT BridgedNativeWidgetImpl
base::scoped_nsobject<NativeWidgetMacNSWindow> window_; base::scoped_nsobject<NativeWidgetMacNSWindow> window_;
base::scoped_nsobject<ViewsNSWindowDelegate> window_delegate_; base::scoped_nsobject<ViewsNSWindowDelegate> window_delegate_;
base::scoped_nsobject<BridgedContentView> bridged_view_; base::scoped_nsobject<BridgedContentView> bridged_view_;
std::unique_ptr<ui::ScopedNSViewIdMapping> bridged_view_id_mapping_;
base::scoped_nsobject<ModalShowAnimationWithLayer> show_animation_; base::scoped_nsobject<ModalShowAnimationWithLayer> show_animation_;
std::unique_ptr<CocoaMouseCapture> mouse_capture_; std::unique_ptr<CocoaMouseCapture> mouse_capture_;
std::unique_ptr<CocoaWindowMoveLoop> window_move_loop_; std::unique_ptr<CocoaWindowMoveLoop> window_move_loop_;
......
...@@ -444,15 +444,19 @@ void BridgedNativeWidgetImpl::DestroyContentView() { ...@@ -444,15 +444,19 @@ void BridgedNativeWidgetImpl::DestroyContentView() {
if (!bridged_view_) if (!bridged_view_)
return; return;
[bridged_view_ clearView]; [bridged_view_ clearView];
bridged_view_id_mapping_.reset();
bridged_view_.reset(); bridged_view_.reset();
[window_ setContentView:nil]; [window_ setContentView:nil];
} }
void BridgedNativeWidgetImpl::CreateContentView(const gfx::Rect& bounds) { void BridgedNativeWidgetImpl::CreateContentView(uint64_t ns_view_id,
const gfx::Rect& bounds) {
DCHECK(!bridged_view_); DCHECK(!bridged_view_);
bridged_view_.reset( bridged_view_.reset(
[[BridgedContentView alloc] initWithBridge:this bounds:bounds]); [[BridgedContentView alloc] initWithBridge:this bounds:bounds]);
bridged_view_id_mapping_ = std::make_unique<ui::ScopedNSViewIdMapping>(
ns_view_id, bridged_view_.get());
// Objective C initializers can return nil. However, if |view| is non-NULL // Objective C initializers can return nil. However, if |view| is non-NULL
// this should be treated as an error and caught early. // this should be treated as an error and caught early.
......
...@@ -65,8 +65,9 @@ interface BridgedNativeWidget { ...@@ -65,8 +65,9 @@ interface BridgedNativeWidget {
// BridgedNativeWidgetHost. // BridgedNativeWidgetHost.
InitCompositorView(); InitCompositorView();
// Create the NSView to be the content view for the window. // Create the NSView to be the content view for the window. Use |ns_view_id|
CreateContentView(gfx.mojom.Rect bounds); // to look up this NSView in other functions (e.g, to specify a parent view).
CreateContentView(uint64 ns_view_id, gfx.mojom.Rect bounds);
// Destroy the content NSView for this window. Note that the window will // Destroy the content NSView for this window. Note that the window will
// become blank once this has been called. // become blank once this has been called.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment