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.
5 #import "ui/views/cocoa/widget_owner_nswindow_adapter.h"
7 #import <Cocoa/Cocoa.h>
9 #include "base/logging.h"
10 #include "ui/gfx/geometry/rect.h"
11 #include "ui/gfx/geometry/vector2d.h"
12 #import "ui/gfx/mac/coordinate_conversion.h"
13 #import "ui/views/cocoa/bridged_native_widget.h"
15 // Bridges an AppKit observer to observe when the (non-views) NSWindow owning a
16 // views::Widget will close.
17 @interface WidgetOwnerNSWindowAdapterBridge : NSObject {
19 views::WidgetOwnerNSWindowAdapter* adapter_; // Weak. Owns us.
21 - (instancetype)initWithAdapter:(views::WidgetOwnerNSWindowAdapter*)adapter;
22 - (void)windowWillClose:(NSNotification*)notification;
25 @implementation WidgetOwnerNSWindowAdapterBridge
27 - (instancetype)initWithAdapter:(views::WidgetOwnerNSWindowAdapter*)adapter {
28 if ((self = [super init]))
33 - (void)windowWillClose:(NSNotification*)notification {
34 adapter_->OnWindowWillClose();
41 WidgetOwnerNSWindowAdapter::WidgetOwnerNSWindowAdapter(
42 BridgedNativeWidget* child,
45 anchor_view_([anchor_view retain]),
47 [[WidgetOwnerNSWindowAdapterBridge alloc] initWithAdapter:this]) {
48 DCHECK([anchor_view_ window]);
49 [[NSNotificationCenter defaultCenter]
50 addObserver:observer_bridge_
51 selector:@selector(windowWillClose:)
52 name:NSWindowWillCloseNotification
53 object:[anchor_view_ window]];
56 void WidgetOwnerNSWindowAdapter::OnWindowWillClose() {
57 [child_->ns_window() close];
58 // Note: |this| will be deleted here.
61 NSWindow* WidgetOwnerNSWindowAdapter::GetNSWindow() {
62 return [anchor_view_ window];
65 gfx::Vector2d WidgetOwnerNSWindowAdapter::GetChildWindowOffset() const {
66 NSWindow* window = [anchor_view_ window];
67 NSRect rect_in_window =
68 [anchor_view_ convertRect:[anchor_view_ bounds] toView:nil];
69 // Ensure we anchor off the top-left of |anchor_view_| (rect_in_window.origin
70 // is the bottom-left of the view).
71 // TODO(tapted): Use -[NSWindow convertRectToScreen:] when we ditch 10.6.
72 NSRect rect_in_screen = NSZeroRect;
73 rect_in_screen.origin =
74 [window convertBaseToScreen:NSMakePoint(NSMinX(rect_in_window),
75 NSMaxY(rect_in_window))];
76 return gfx::ScreenRectFromNSRect(rect_in_screen).OffsetFromOrigin();
79 bool WidgetOwnerNSWindowAdapter::IsVisibleParent() const {
80 return [[anchor_view_ window] isVisible];
83 void WidgetOwnerNSWindowAdapter::RemoveChildWindow(BridgedNativeWidget* child) {
84 DCHECK_EQ(child, child_);
85 [GetNSWindow() removeChildWindow:child->ns_window()];
89 WidgetOwnerNSWindowAdapter::~WidgetOwnerNSWindowAdapter() {
90 [[NSNotificationCenter defaultCenter] removeObserver:observer_bridge_];