Automated Commit: Committing new LKGM version 7479.0.0 for chromeos.
[chromium-blink-merge.git] / ui / views / cocoa / widget_owner_nswindow_adapter.mm
blob0fbe5d545c29c9ea7262a4c7e46fa61f04d06c56
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 {
18  @private
19   views::WidgetOwnerNSWindowAdapter* adapter_;  // Weak. Owns us.
21 - (instancetype)initWithAdapter:(views::WidgetOwnerNSWindowAdapter*)adapter;
22 - (void)windowWillClose:(NSNotification*)notification;
23 @end
25 @implementation WidgetOwnerNSWindowAdapterBridge
27 - (instancetype)initWithAdapter:(views::WidgetOwnerNSWindowAdapter*)adapter {
28   if ((self = [super init]))
29     adapter_ = adapter;
30   return self;
33 - (void)windowWillClose:(NSNotification*)notification {
34   adapter_->OnWindowWillClose();
37 @end
39 namespace views {
41 WidgetOwnerNSWindowAdapter::WidgetOwnerNSWindowAdapter(
42     BridgedNativeWidget* child,
43     NSView* anchor_view)
44     : child_(child),
45       anchor_view_([anchor_view retain]),
46       observer_bridge_(
47           [[WidgetOwnerNSWindowAdapterBridge alloc] initWithAdapter:this]) {
49   // Although the |anchor_view| must be in an NSWindow when the child dialog is
50   // created, it's permitted for the |anchor_view| to be removed from its view
51   // hierarchy before the child dialog window is fully removed from screen. When
52   // this happens, [anchor_view_ window] will become nil, so retain both.
53   anchor_window_.reset([[anchor_view_ window] retain]);
54   DCHECK(anchor_window_);
56   [[NSNotificationCenter defaultCenter]
57       addObserver:observer_bridge_
58          selector:@selector(windowWillClose:)
59              name:NSWindowWillCloseNotification
60            object:anchor_window_];
63 void WidgetOwnerNSWindowAdapter::OnWindowWillClose() {
64   [child_->ns_window() close];
65   // Note: |this| will be deleted here.
68 NSWindow* WidgetOwnerNSWindowAdapter::GetNSWindow() {
69   return anchor_window_;
72 gfx::Vector2d WidgetOwnerNSWindowAdapter::GetChildWindowOffset() const {
73   NSRect rect_in_window =
74       [anchor_view_ convertRect:[anchor_view_ bounds] toView:nil];
75   // Ensure we anchor off the top-left of |anchor_view_| (rect_in_window.origin
76   // is the bottom-left of the view).
77   // TODO(tapted): Use -[NSWindow convertRectToScreen:] when we ditch 10.6.
78   NSRect rect_in_screen = NSZeroRect;
79   rect_in_screen.origin =
80       [anchor_window_ convertBaseToScreen:NSMakePoint(NSMinX(rect_in_window),
81                                                       NSMaxY(rect_in_window))];
82   return gfx::ScreenRectFromNSRect(rect_in_screen).OffsetFromOrigin();
85 bool WidgetOwnerNSWindowAdapter::IsVisibleParent() const {
86   return [anchor_window_ isVisible];
89 void WidgetOwnerNSWindowAdapter::RemoveChildWindow(BridgedNativeWidget* child) {
90   DCHECK_EQ(child, child_);
91   [GetNSWindow() removeChildWindow:child->ns_window()];
92   delete this;
95 WidgetOwnerNSWindowAdapter::~WidgetOwnerNSWindowAdapter() {
96   [[NSNotificationCenter defaultCenter] removeObserver:observer_bridge_];
99 }  // namespace views