Commit f3334641 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

RemoteMacViews: Remove browser deps from NativeWidgetMacNSWindow

Update NativeWidgetMacNSWindow to use the mojo BridgeNativeWidgetHost
interface instead of directly dereferencing views structures. Make
similar changes to ViewsNSWindowDelegate. Update the mojo interfaces
to include these functions.

Remove the nativeWidgetMac property from ViewsNSWindowDelegate.
Replace it with an "id" uint64_t on NativeWidgetMacNSWindow, which
can be used to look up a corresponding
- BridgedNativeWidgetImpl (in the app/viewer process)
- BridgedNativeWidgetHostImpl (in the browser process)
  - a follow-on patch will add a "shadow" NativeWidgetMacNSWindow
    in the browser process which will use this id
  - that window will not be visible, but will be used for state
    tracking and bounds computations

Bug: 859152
Change-Id: I9f62aefa1d4eba9961f691b5bd9247871e121355
Reviewed-on: https://chromium-review.googlesource.com/1205477Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589415}
parent b4b5657d
......@@ -67,8 +67,12 @@ class VIEWS_EXPORT BridgedNativeWidgetImpl
static gfx::Size GetWindowSizeForClientSize(NSWindow* window,
const gfx::Size& size);
// Retrieve a BridgedNativeWidgetImpl* from its id.
static BridgedNativeWidgetImpl* GetFromId(uint64_t bridged_native_widget_id);
// Creates one side of the bridge. |host| and |parent| must not be NULL.
BridgedNativeWidgetImpl(BridgedNativeWidgetHost* host,
BridgedNativeWidgetImpl(uint64_t bridged_native_widget_id,
BridgedNativeWidgetHost* host,
BridgedNativeWidgetHostHelper* host_helper,
NativeWidgetMac* parent);
~BridgedNativeWidgetImpl() override;
......@@ -291,6 +295,7 @@ class VIEWS_EXPORT BridgedNativeWidgetImpl
bool IsVisibleParent() const override;
void RemoveChildWindow(BridgedNativeWidgetImpl* child) override;
const uint64_t id_;
BridgedNativeWidgetHost* const host_; // Weak. Owns this.
BridgedNativeWidgetHostHelper* const host_helper_; // Weak, owned by |host_|.
NativeWidgetMac* const native_widget_mac_; // Weak. Owns |host_|.
......
......@@ -13,6 +13,7 @@
#import "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#import "base/mac/sdk_forward_declarations.h"
#include "base/no_destructor.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/sys_string_conversions.h"
#include "ui/base/cocoa/cocoa_base_utils.h"
......@@ -137,6 +138,8 @@ constexpr auto kUIPaintTimeout = base::TimeDelta::FromSeconds(5);
}
@end
namespace views {
namespace {
using RankMap = std::map<NSView*, int>;
......@@ -178,8 +181,8 @@ gfx::Size GetClientSizeForWindowSize(NSWindow* window,
return gfx::Size([window contentRectForFrameRect:frame_rect].size);
}
void RankNSViews(views::View* view,
const views::BridgedNativeWidgetImpl::AssociatedViews& hosts,
void RankNSViews(View* view,
const BridgedNativeWidgetImpl::AssociatedViews& hosts,
RankMap* rank) {
auto it = hosts.find(view);
if (it != hosts.end())
......@@ -223,9 +226,10 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
return count;
}
} // namespace
static base::NoDestructor<std::map<uint64_t, BridgedNativeWidgetImpl*>>
g_id_map;
namespace views {
} // namespace
// static
gfx::Size BridgedNativeWidgetImpl::GetWindowSizeForClientSize(
......@@ -237,18 +241,36 @@ gfx::Size BridgedNativeWidgetImpl::GetWindowSizeForClientSize(
return gfx::Size(NSWidth(frame_rect), NSHeight(frame_rect));
}
// static
BridgedNativeWidgetImpl* BridgedNativeWidgetImpl::GetFromId(
uint64_t bridged_native_widget_id) {
auto found = g_id_map.get()->find(bridged_native_widget_id);
if (found == g_id_map.get()->end())
return nullptr;
return found->second;
}
BridgedNativeWidgetImpl::BridgedNativeWidgetImpl(
uint64_t bridged_native_widget_id,
BridgedNativeWidgetHost* host,
BridgedNativeWidgetHostHelper* host_helper,
NativeWidgetMac* parent)
: host_(host), host_helper_(host_helper), native_widget_mac_(parent) {
: id_(bridged_native_widget_id),
host_(host),
host_helper_(host_helper),
native_widget_mac_(parent) {
DCHECK(g_id_map.get()->find(id_) == g_id_map.get()->end());
g_id_map.get()->insert(std::make_pair(id_, this));
DCHECK(parent);
window_delegate_.reset(
[[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]);
ui::CATransactionCoordinator::Get().AddPreCommitObserver(this);
}
BridgedNativeWidgetImpl::~BridgedNativeWidgetImpl() {
// Ensure that |this| cannot be reached by its id while it is being destroyed.
auto found = g_id_map.get()->find(id_);
DCHECK(found != g_id_map.get()->end());
DCHECK_EQ(found->second, this);
g_id_map.get()->erase(found);
// The delegate should be cleared already. Note this enforces the precondition
// that -[NSWindow close] is invoked on the hosted window before the
// destructor is called.
......@@ -263,9 +285,13 @@ BridgedNativeWidgetImpl::~BridgedNativeWidgetImpl() {
void BridgedNativeWidgetImpl::SetWindow(
base::scoped_nsobject<NativeWidgetMacNSWindow> window) {
DCHECK(!window_);
window_delegate_.reset(
[[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]);
window_ = std::move(window);
[window_ setBridgedNativeWidgetId:id_];
[window_ setReleasedWhenClosed:NO]; // Owned by scoped_nsobject.
[window_ setDelegate:window_delegate_];
ui::CATransactionCoordinator::Get().AddPreCommitObserver(this);
}
void BridgedNativeWidgetImpl::SetParent(NSView* new_parent) {
......@@ -426,7 +452,7 @@ void BridgedNativeWidgetImpl::CreateContentView(const gfx::Rect& bounds) {
[window_ setContentView:bridged_view_];
}
void BridgedNativeWidgetImpl::CreateDragDropClient(views::View* view) {
void BridgedNativeWidgetImpl::CreateDragDropClient(View* view) {
drag_drop_client_.reset(new DragDropClientMac(this, view));
}
......@@ -880,14 +906,14 @@ void BridgedNativeWidgetImpl::InitCompositorView() {
UpdateWindowGeometry();
}
void BridgedNativeWidgetImpl::SetAssociationForView(const views::View* view,
void BridgedNativeWidgetImpl::SetAssociationForView(const View* view,
NSView* native_view) {
DCHECK_EQ(0u, associated_views_.count(view));
associated_views_[view] = native_view;
native_widget_mac_->GetWidget()->ReorderNativeViews();
}
void BridgedNativeWidgetImpl::ClearAssociationForView(const views::View* view) {
void BridgedNativeWidgetImpl::ClearAssociationForView(const View* view) {
auto it = associated_views_.find(view);
DCHECK(it != associated_views_.end());
associated_views_.erase(it);
......
......@@ -48,6 +48,12 @@ class VIEWS_EXPORT BridgedNativeWidgetHostHelper {
bool* found_word,
gfx::DecoratedText* decorated_word,
gfx::Point* baseline_point) = 0;
// Returns the vertical position that sheets should be anchored, in pixels
// from the bottom of the window.
// TODO(ccameron): This should be either moved to the mojo interface or
// separated out in such a way as to avoid needing to go through mojo.
virtual double SheetPositionY() = 0;
};
} // namespace views
......
......@@ -46,15 +46,30 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
public ui::LayerOwner,
public ui::AcceleratedWidgetMacNSView {
public:
// Unique integer id handles are used to bridge between the
// BridgedNativeWidgetHostImpl in one process and the BridgedNativeWidgetHost
// potentially in another.
static BridgedNativeWidgetHostImpl* GetFromId(
uint64_t bridged_native_widget_id);
uint64_t bridged_native_widget_id() const { return id_; }
// Creates one side of the bridge. |parent| must not be NULL.
explicit BridgedNativeWidgetHostImpl(NativeWidgetMac* parent);
~BridgedNativeWidgetHostImpl() override;
// Provide direct access to the BridgedNativeWidgetImpl that this is hosting.
// The NativeWidgetMac that owns |this|.
views::NativeWidgetMac* native_widget_mac() const {
return native_widget_mac_;
}
// The mojo interface through which to communicate with the underlying
// NSWindow and NSView.
views_bridge_mac::mojom::BridgedNativeWidget* bridge() const;
// Direct access to the BridgedNativeWidgetImpl that this is hosting.
// TODO(ccameron): Remove all accesses to this member, and replace them
// with methods that may be sent across processes.
BridgedNativeWidgetImpl* bridge_impl() const { return bridge_impl_.get(); }
views_bridge_mac::mojom::BridgedNativeWidget* bridge() const;
TooltipManager* tooltip_manager() { return tooltip_manager_.get(); }
......@@ -132,6 +147,7 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
bool* found_word,
gfx::DecoratedText* decorated_word,
gfx::Point* baseline_point) override;
double SheetPositionY() override;
// views_bridge_mac::mojom::BridgedNativeWidgetHost:
void OnVisibilityChanged(bool visible) override;
......@@ -174,6 +190,10 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
bool* is_button_enabled,
bool* is_button_default) override;
bool GetDoDialogButtonsExist(bool* buttons_exist) override;
bool GetShouldShowWindowTitle(bool* should_show_window_title) override;
bool GetCanWindowBecomeKey(bool* can_window_become_key) override;
bool GetAlwaysRenderWindowAsKey(bool* always_render_as_key) override;
bool GetCanWindowClose(bool* can_window_close) override;
// views_bridge_mac::mojom::BridgedNativeWidgetHost, synchronous callbacks:
void DispatchKeyEventRemote(std::unique_ptr<ui::Event> event,
......@@ -194,6 +214,12 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
GetDialogButtonInfoCallback callback) override;
void GetDoDialogButtonsExist(
GetDoDialogButtonsExistCallback callback) override;
void GetShouldShowWindowTitle(
GetShouldShowWindowTitleCallback callback) override;
void GetCanWindowBecomeKey(GetCanWindowBecomeKeyCallback callback) override;
void GetAlwaysRenderWindowAsKey(
GetAlwaysRenderWindowAsKeyCallback callback) override;
void GetCanWindowClose(GetCanWindowCloseCallback callback) override;
// DialogObserver:
void OnDialogModelChanged() override;
......@@ -213,6 +239,7 @@ class VIEWS_EXPORT BridgedNativeWidgetHostImpl
// ui::AcceleratedWidgetMacNSView:
void AcceleratedWidgetCALayerParamsUpdated() override;
const uint64_t id_;
views::NativeWidgetMac* const native_widget_mac_; // Weak. Owns |this_|.
Widget::InitParams::Type widget_type_ = Widget::InitParams::TYPE_WINDOW;
......
......@@ -41,14 +41,38 @@ bool PositionWindowInScreenCoordinates(Widget* widget,
return widget && widget->is_top_level();
}
base::NoDestructor<std::map<uint64_t, BridgedNativeWidgetHostImpl*>> g_id_map;
uint64_t g_last_bridged_native_widget_id = 0;
} // namespace
// static
BridgedNativeWidgetHostImpl* BridgedNativeWidgetHostImpl::GetFromId(
uint64_t bridged_native_widget_id) {
auto found = g_id_map.get()->find(bridged_native_widget_id);
if (found == g_id_map.get()->end())
return nullptr;
return found->second;
}
BridgedNativeWidgetHostImpl::BridgedNativeWidgetHostImpl(
NativeWidgetMac* parent)
: native_widget_mac_(parent),
bridge_impl_(new BridgedNativeWidgetImpl(this, this, parent)) {}
: id_(++g_last_bridged_native_widget_id),
native_widget_mac_(parent),
bridge_impl_(new BridgedNativeWidgetImpl(id_, this, this, parent)) {
DCHECK(g_id_map.get()->find(id_) == g_id_map.get()->end());
g_id_map.get()->insert(std::make_pair(id_, this));
DCHECK(parent);
}
BridgedNativeWidgetHostImpl::~BridgedNativeWidgetHostImpl() {
// Ensure that |this| cannot be reached by its id while it is being destroyed.
auto found = g_id_map.get()->find(id_);
DCHECK(found != g_id_map.get()->end());
DCHECK_EQ(found->second, this);
g_id_map.get()->erase(found);
// Destroy the bridge first to prevent any calls back into this during
// destruction.
// TODO(ccameron): When all communication from |bridge_| to this goes through
......@@ -292,6 +316,10 @@ bool BridgedNativeWidgetHostImpl::DispatchKeyEventToMenuController(
return false;
}
double BridgedNativeWidgetHostImpl::SheetPositionY() {
return native_widget_mac_->SheetPositionY();
}
////////////////////////////////////////////////////////////////////////////////
// BridgedNativeWidgetHostImpl,
// views_bridge_mac::mojom::BridgedNativeWidgetHost:
......@@ -583,6 +611,38 @@ bool BridgedNativeWidgetHostImpl::GetDoDialogButtonsExist(bool* buttons_exist) {
return true;
}
bool BridgedNativeWidgetHostImpl::GetShouldShowWindowTitle(
bool* should_show_window_title) {
*should_show_window_title =
root_view_
? root_view_->GetWidget()->widget_delegate()->ShouldShowWindowTitle()
: true;
return true;
}
bool BridgedNativeWidgetHostImpl::GetCanWindowBecomeKey(
bool* can_window_become_key) {
*can_window_become_key =
root_view_ ? root_view_->GetWidget()->CanActivate() : false;
return true;
}
bool BridgedNativeWidgetHostImpl::GetAlwaysRenderWindowAsKey(
bool* always_render_as_key) {
*always_render_as_key =
root_view_ ? root_view_->GetWidget()->IsAlwaysRenderAsActive() : false;
return true;
}
bool BridgedNativeWidgetHostImpl::GetCanWindowClose(bool* can_window_close) {
*can_window_close = true;
views::NonClientView* non_client_view =
root_view_ ? root_view_->GetWidget()->non_client_view() : nullptr;
if (non_client_view)
*can_window_close = non_client_view->CanClose();
return true;
}
////////////////////////////////////////////////////////////////////////////////
// BridgedNativeWidgetHostImpl,
// views_bridge_mac::mojom::BridgedNativeWidgetHost synchronous callbacks:
......@@ -658,6 +718,34 @@ void BridgedNativeWidgetHostImpl::GetDoDialogButtonsExist(
std::move(callback).Run(buttons_exist);
}
void BridgedNativeWidgetHostImpl::GetShouldShowWindowTitle(
GetShouldShowWindowTitleCallback callback) {
bool should_show_window_title = false;
GetShouldShowWindowTitle(&should_show_window_title);
std::move(callback).Run(should_show_window_title);
}
void BridgedNativeWidgetHostImpl::GetCanWindowBecomeKey(
GetCanWindowBecomeKeyCallback callback) {
bool can_window_become_key = false;
GetCanWindowBecomeKey(&can_window_become_key);
std::move(callback).Run(can_window_become_key);
}
void BridgedNativeWidgetHostImpl::GetAlwaysRenderWindowAsKey(
GetAlwaysRenderWindowAsKeyCallback callback) {
bool always_render_as_key = false;
GetAlwaysRenderWindowAsKey(&always_render_as_key);
std::move(callback).Run(always_render_as_key);
}
void BridgedNativeWidgetHostImpl::GetCanWindowClose(
GetCanWindowCloseCallback callback) {
bool can_window_close = false;
GetCanWindowClose(&can_window_close);
std::move(callback).Run(can_window_close);
}
////////////////////////////////////////////////////////////////////////////////
// BridgedNativeWidgetHostImpl, DialogObserver:
......@@ -682,7 +770,10 @@ void BridgedNativeWidgetHostImpl::OnDidChangeFocus(View* focused_before,
// Sanity check: When focus moves away from the widget (i.e. |focused_now|
// is nil), then the textInputClient will be cleared.
DCHECK(!!focused_now || !input_client);
bridge_impl_->SetTextInputClient(input_client);
// TODO(ccameron): TextInputClient is not handled across process borders
// yet.
if (bridge_impl_)
bridge_impl_->SetTextInputClient(input_client);
}
}
......
......@@ -47,6 +47,10 @@ VIEWS_EXPORT
// create one.
- (void)setWindowTouchBarDelegate:(id<WindowTouchBarDelegate>)delegate;
// Identifier for the NativeWidgetMac from which this window was created. This
// may be used to look up the BridgedNativeWidgetHostImpl in the browser process
// or the BridgedNativeWidgetImpl in a display process.
@property(assign, nonatomic) uint64_t bridgedNativeWidgetId;
@end
#endif // UI_VIEWS_COCOA_NATIVE_WIDGET_MAC_NSWINDOW_H_
......@@ -9,11 +9,11 @@
#import "ui/base/cocoa/user_interface_item_command_handler.h"
#import "ui/base/cocoa/window_size_constants.h"
#import "ui/views/cocoa/bridged_native_widget.h"
#import "ui/views/cocoa/bridged_native_widget_host.h"
#import "ui/views/cocoa/views_nswindow_delegate.h"
#import "ui/views/cocoa/window_touch_bar_delegate.h"
#include "ui/views/controls/menu/menu_controller.h"
#include "ui/views/widget/native_widget_mac.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views_bridge_mac/mojo/bridged_native_widget_host.mojom.h"
@interface NSWindow (Private)
+ (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle;
......@@ -27,13 +27,15 @@
@interface NativeWidgetMacNSWindow ()
- (ViewsNSWindowDelegate*)viewsNSWindowDelegate;
- (views::Widget*)viewsWidget;
- (BOOL)hasViewsMenuActive;
- (id)rootAccessibilityObject;
// Private API on NSWindow, determines whether the title is drawn on the title
// bar. The title is still visible in menus, Expose, etc.
- (BOOL)_isTitleHidden;
// Retrieve the corresponding views::BridgedNativeWidgetImpl in this process.
- (views::BridgedNativeWidgetImpl*)bridgeImpl;
@end
// Use this category to implement mouseDown: on multiple frame view classes
......@@ -83,7 +85,9 @@
base::scoped_nsobject<CommandDispatcher> commandDispatcher_;
base::scoped_nsprotocol<id<UserInterfaceItemCommandHandler>> commandHandler_;
id<WindowTouchBarDelegate> touchBarDelegate_; // Weak.
uint64_t bridgedNativeWidgetId_;
}
@synthesize bridgedNativeWidgetId = bridgedNativeWidgetId_;
- (instancetype)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)windowStyle
......@@ -132,19 +136,18 @@
return base::mac::ObjCCastStrict<ViewsNSWindowDelegate>([self delegate]);
}
- (views::Widget*)viewsWidget {
return [[self viewsNSWindowDelegate] nativeWidgetMac]->GetWidget();
- (views::BridgedNativeWidgetImpl*)bridgeImpl {
return views::BridgedNativeWidgetImpl::GetFromId(bridgedNativeWidgetId_);
}
- (BOOL)hasViewsMenuActive {
views::MenuController* menuController =
views::MenuController::GetActiveInstance();
return menuController && menuController->owner() == [self viewsWidget];
bool hasMenuController = false;
[self bridgeImpl]->host()->GetHasMenuController(&hasMenuController);
return hasMenuController;
}
- (id)rootAccessibilityObject {
views::Widget* widget = [self viewsWidget];
return widget ? widget->GetRootView()->GetNativeViewAccessible() : nil;
return [self bridgeImpl]->host_helper()->GetNativeViewAccessible();
}
// NSWindow overrides.
......@@ -161,10 +164,10 @@
}
- (BOOL)_isTitleHidden {
if (![self delegate])
return NO;
return ![self viewsWidget]->widget_delegate()->ShouldShowWindowTitle();
bool shouldShowWindowTitle = YES;
if ([self bridgeImpl])
[self bridgeImpl]->host()->GetShouldShowWindowTitle(&shouldShowWindowTitle);
return !shouldShowWindowTitle;
}
// The base implementation returns YES if the window's frame view is a custom
......@@ -179,23 +182,36 @@
// Note these can be called via -[NSWindow close] while the widget is being torn
// down, so check for a delegate.
- (BOOL)canBecomeKeyWindow {
return [self delegate] && [self viewsWidget]->CanActivate();
bool canBecomeKey = NO;
if ([self bridgeImpl])
[self bridgeImpl]->host()->GetCanWindowBecomeKey(&canBecomeKey);
return canBecomeKey;
}
- (BOOL)canBecomeMainWindow {
if (![self delegate])
views::BridgedNativeWidgetImpl* bridgeImpl = [self bridgeImpl];
if (!bridgeImpl)
return NO;
// Dialogs and bubbles shouldn't take large shadows away from their parent.
views::Widget* widget = [self viewsWidget];
return widget->CanActivate() &&
!views::NativeWidgetMac::GetBridgeImplForNativeWindow(self)->parent();
if (bridgeImpl->parent())
return NO;
bool canBecomeKey = NO;
if (bridgeImpl)
bridgeImpl->host()->GetCanWindowBecomeKey(&canBecomeKey);
return canBecomeKey;
}
// Lets the traffic light buttons on the parent window keep their active state.
- (BOOL)hasKeyAppearance {
if ([self delegate] && [self viewsWidget]->IsAlwaysRenderAsActive())
return YES;
views::BridgedNativeWidgetImpl* bridgeImpl = [self bridgeImpl];
if (bridgeImpl) {
bool isAlwaysRenderWindowAsKey = NO;
bridgeImpl->host()->GetAlwaysRenderWindowAsKey(&isAlwaysRenderWindowAsKey);
if (isAlwaysRenderWindowAsKey)
return YES;
}
return [super hasKeyAppearance];
}
......@@ -312,12 +328,12 @@
// Additionally, if we don't do this, VoiceOver reads out the partial a11y
// properties on the NSWindow and repeats them when focusing an item in the
// RootView's a11y group. See http://crbug.com/748221.
views::Widget* widget = [self viewsWidget];
id superFocus = [super accessibilityFocusedUIElement];
if (!widget || superFocus != self)
views::BridgedNativeWidgetImpl* bridgeImpl = [self bridgeImpl];
if (!bridgeImpl || superFocus != self)
return superFocus;
return widget->GetRootView()->GetNativeViewAccessible();
return bridgeImpl->host_helper()->GetNativeViewAccessible();
}
- (id)accessibilityAttributeValue:(NSString*)attribute {
......
......@@ -11,7 +11,6 @@
#include "ui/views/views_export.h"
namespace views {
class NativeWidgetMac;
class BridgedNativeWidgetImpl;
}
......@@ -24,10 +23,6 @@ VIEWS_EXPORT
base::scoped_nsobject<NSCursor> cursor_;
}
// The NativeWidgetMac that created the window this is attached to. Returns
// NULL if not created by NativeWidgetMac.
@property(nonatomic, readonly) views::NativeWidgetMac* nativeWidgetMac;
// If set, the cursor set in -[NSResponder updateCursor:] when the window is
// reached along the responder chain.
@property(retain, nonatomic) NSCursor* cursor;
......
......@@ -10,7 +10,6 @@
#import "ui/views/cocoa/bridged_content_view.h"
#import "ui/views/cocoa/bridged_native_widget.h"
#include "ui/views/cocoa/bridged_native_widget_host.h"
#include "ui/views/widget/native_widget_mac.h"
#include "ui/views_bridge_mac/mojo/bridged_native_widget_host.mojom.h"
@implementation ViewsNSWindowDelegate
......@@ -23,10 +22,6 @@
return self;
}
- (views::NativeWidgetMac*)nativeWidgetMac {
return parent_->native_widget_mac();
}
- (NSCursor*)cursor {
return cursor_.get();
}
......@@ -124,9 +119,9 @@
}
- (BOOL)windowShouldClose:(id)sender {
views::NonClientView* nonClientView =
[self nativeWidgetMac]->GetWidget()->non_client_view();
return !nonClientView || nonClientView->CanClose();
bool canWindowClose = true;
parent_->host()->GetCanWindowClose(&canWindowClose);
return canWindowClose;
}
- (void)windowWillClose:(NSNotification*)notification {
......@@ -200,12 +195,15 @@
- (NSRect)window:(NSWindow*)window
willPositionSheet:(NSWindow*)sheet
usingRect:(NSRect)defaultSheetLocation {
// TODO(ccameron): This should go through the BridgedNativeWidgetHost
// interface.
CGFloat sheetPositionY = parent_->host_helper()->SheetPositionY();
// As per NSWindowDelegate documentation, the origin indicates the top left
// point of the host frame in window coordinates. The width changes the
// animation from vertical to trapezoid if it is smaller than the width of the
// dialog. The height is ignored but should be set to zero.
return NSMakeRect(0, [self nativeWidgetMac]->SheetPositionY(),
NSWidth(defaultSheetLocation), 0);
return NSMakeRect(0, sheetPositionY, NSWidth(defaultSheetLocation), 0);
}
@end
......@@ -44,17 +44,6 @@ namespace {
base::LazyInstance<ui::GestureRecognizerImplMac>::Leaky
g_gesture_recognizer_instance = LAZY_INSTANCE_INITIALIZER;
NativeWidgetMac* GetNativeWidgetMacForNativeWindow(
gfx::NativeWindow native_window) {
id<NSWindowDelegate> window_delegate = [native_window delegate];
if ([window_delegate respondsToSelector:@selector(nativeWidgetMac)]) {
ViewsNSWindowDelegate* delegate =
base::mac::ObjCCastStrict<ViewsNSWindowDelegate>(window_delegate);
return [delegate nativeWidgetMac];
}
return nullptr; // Not created by NativeWidgetMac.
}
NSInteger StyleMaskForParams(const Widget::InitParams& params) {
// If the Widget is modal, it will be displayed as a sheet. This works best if
// it has NSTitledWindowMask. For example, with NSBorderlessWindowMask, the
......@@ -95,16 +84,22 @@ NativeWidgetMac::~NativeWidgetMac() {
// static
BridgedNativeWidgetImpl* NativeWidgetMac::GetBridgeImplForNativeWindow(
gfx::NativeWindow window) {
if (NativeWidgetMac* widget = GetNativeWidgetMacForNativeWindow(window))
return widget->bridge_impl();
if (NativeWidgetMacNSWindow* widget_window =
base::mac::ObjCCast<NativeWidgetMacNSWindow>(window)) {
return BridgedNativeWidgetImpl::GetFromId(
[widget_window bridgedNativeWidgetId]);
}
return nullptr; // Not created by NativeWidgetMac.
}
// static
BridgedNativeWidgetHostImpl* NativeWidgetMac::GetBridgeHostImplForNativeWindow(
gfx::NativeWindow window) {
if (NativeWidgetMac* widget = GetNativeWidgetMacForNativeWindow(window))
return widget->bridge_host_.get();
if (NativeWidgetMacNSWindow* widget_window =
base::mac::ObjCCast<NativeWidgetMacNSWindow>(window)) {
return BridgedNativeWidgetHostImpl::GetFromId(
[widget_window bridgedNativeWidgetId]);
}
return nullptr; // Not created by NativeWidgetMac.
}
......@@ -152,7 +147,8 @@ void NativeWidgetMac::InitNativeWidget(const Widget::InitParams& params) {
DCHECK(GetWidget()->GetRootView());
bridge_host_->SetRootView(GetWidget()->GetRootView());
bridge()->CreateContentView(GetWidget()->GetRootView()->bounds());
bridge_impl()->CreateDragDropClient(GetWidget()->GetRootView());
if (bridge_impl())
bridge_impl()->CreateDragDropClient(GetWidget()->GetRootView());
if (auto* focus_manager = GetWidget()->GetFocusManager()) {
bridge()->MakeFirstResponder();
bridge_host_->SetFocusManager(focus_manager);
......@@ -697,8 +693,10 @@ NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
// static
NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
gfx::NativeWindow window) {
if (NativeWidgetMac* widget = GetNativeWidgetMacForNativeWindow(window))
return widget;
if (BridgedNativeWidgetHostImpl* bridge_host_impl =
NativeWidgetMac::GetBridgeHostImplForNativeWindow(window)) {
return bridge_host_impl->native_widget_mac();
}
return nullptr; // Not created by NativeWidgetMac.
}
......
......@@ -134,4 +134,23 @@ interface BridgedNativeWidgetHost {
// for the current dialog.
[Sync]
GetDoDialogButtonsExist() => (bool buttons_exist);
// Synchronously query if the NSWindow should display its title.
[Sync]
GetShouldShowWindowTitle() => (bool should_show_window_title);
// Synchronously query if the NSWindow can become key (activate, in views
// terminology).
[Sync]
GetCanWindowBecomeKey() => (bool can_window_become_key);
// Synchronously query if the NSWindow should always render as if it is
// the key window (is active, in views terminology).
[Sync]
GetAlwaysRenderWindowAsKey() => (bool always_render_as_key);
// Synchronously query if the NSWindow should always render as if it is
// the key window (is active, in views terminology).
[Sync]
GetCanWindowClose() => (bool can_window_close);
};
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