Roll src/third_party/skia d32087a:1052f51
[chromium-blink-merge.git] / ui / views / widget / native_widget_mac.mm
blob1b5b2eb12bc14eaadd885b7c75d71d0eca11636b
1 // Copyright 2014 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 #include "ui/views/widget/native_widget_mac.h"
7 #import <Cocoa/Cocoa.h>
9 #include "base/mac/foundation_util.h"
10 #include "base/mac/scoped_nsobject.h"
11 #include "base/strings/sys_string_conversions.h"
12 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
13 #import "ui/base/cocoa/window_size_constants.h"
14 #include "ui/gfx/font_list.h"
15 #import "ui/gfx/mac/coordinate_conversion.h"
16 #import "ui/gfx/mac/nswindow_frame_controls.h"
17 #include "ui/native_theme/native_theme.h"
18 #import "ui/views/cocoa/bridged_content_view.h"
19 #import "ui/views/cocoa/bridged_native_widget.h"
20 #import "ui/views/cocoa/native_widget_mac_nswindow.h"
21 #import "ui/views/cocoa/views_nswindow_delegate.h"
22 #include "ui/views/widget/widget_delegate.h"
23 #include "ui/views/window/native_frame_view.h"
25 // Self-owning animation delegate that starts a hide animation, then calls
26 // -[NSWindow close] when the animation ends, releasing itself.
27 @interface ViewsNSWindowCloseAnimator : NSObject<NSAnimationDelegate> {
28  @private
29   base::scoped_nsobject<NSWindow> window_;
30   base::scoped_nsobject<NSAnimation> animation_;
33 + (void)closeWindowWithAnimation:(NSWindow*)window;
35 @end
37 namespace views {
38 namespace {
40 NSInteger StyleMaskForParams(const Widget::InitParams& params) {
41   // If the Widget is modal, it will be displayed as a sheet. This works best if
42   // it has NSTitledWindowMask. For example, with NSBorderlessWindowMask, the
43   // parent window still accepts input.
44   if (params.delegate &&
45       params.delegate->GetModalType() == ui::MODAL_TYPE_WINDOW)
46     return NSTitledWindowMask;
48   // TODO(tapted): Determine better masks when there are use cases for it.
49   if (params.remove_standard_frame)
50     return NSBorderlessWindowMask;
52   if (params.type == Widget::InitParams::TYPE_WINDOW) {
53     return NSTitledWindowMask | NSClosableWindowMask |
54            NSMiniaturizableWindowMask | NSResizableWindowMask |
55            NSTexturedBackgroundWindowMask;
56   }
57   return NSBorderlessWindowMask;
60 }  // namespace
62 ////////////////////////////////////////////////////////////////////////////////
63 // NativeWidgetMac, public:
65 NativeWidgetMac::NativeWidgetMac(internal::NativeWidgetDelegate* delegate)
66     : delegate_(delegate),
67       bridge_(new BridgedNativeWidget(this)),
68       ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) {
71 NativeWidgetMac::~NativeWidgetMac() {
72   if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
73     delete delegate_;
74   else
75     CloseNow();
78 // static
79 BridgedNativeWidget* NativeWidgetMac::GetBridgeForNativeWindow(
80     gfx::NativeWindow window) {
81   id<NSWindowDelegate> window_delegate = [window delegate];
82   if ([window_delegate respondsToSelector:@selector(nativeWidgetMac)]) {
83     ViewsNSWindowDelegate* delegate =
84         base::mac::ObjCCastStrict<ViewsNSWindowDelegate>(window_delegate);
85     return [delegate nativeWidgetMac]->bridge_.get();
86   }
87   return nullptr;  // Not created by NativeWidgetMac.
90 bool NativeWidgetMac::IsWindowModalSheet() const {
91   return GetWidget()->widget_delegate()->GetModalType() ==
92          ui::MODAL_TYPE_WINDOW;
95 void NativeWidgetMac::OnWindowWillClose() {
96   // Note: If closed via CloseNow(), |bridge_| will already be reset. If closed
97   // by the user, or via Close() and a RunLoop, notify observers while |bridge_|
98   // is still a valid pointer, then reset it.
99   if (bridge_) {
100     delegate_->OnNativeWidgetDestroying();
101     bridge_.reset();
102   }
103   delegate_->OnNativeWidgetDestroyed();
104   if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
105     delete this;
108 int NativeWidgetMac::SheetPositionY() {
109   NSView* view = GetNativeView();
110   return
111       [view convertPoint:NSMakePoint(0, NSHeight([view frame])) toView:nil].y;
114 ////////////////////////////////////////////////////////////////////////////////
115 // NativeWidgetMac, internal::NativeWidgetPrivate implementation:
117 void NativeWidgetMac::InitNativeWidget(const Widget::InitParams& params) {
118   ownership_ = params.ownership;
119   base::scoped_nsobject<NSWindow> window([CreateNSWindow(params) retain]);
120   [window setReleasedWhenClosed:NO];  // Owned by scoped_nsobject.
121   bridge_->Init(window, params);
123   // Only set always-on-top here if it is true since setting it may affect how
124   // the window is treated by Expose.
125   if (params.keep_on_top)
126     SetAlwaysOnTop(true);
128   delegate_->OnNativeWidgetCreated(true);
130   bridge_->SetFocusManager(GetWidget()->GetFocusManager());
132   DCHECK(GetWidget()->GetRootView());
133   bridge_->SetRootView(GetWidget()->GetRootView());
135   // "Infer" must be handled by ViewsDelegate::OnBeforeWidgetInit().
136   DCHECK_NE(Widget::InitParams::INFER_OPACITY, params.opacity);
137   bool translucent = params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW;
138   bridge_->CreateLayer(params.layer_type, translucent);
141 NonClientFrameView* NativeWidgetMac::CreateNonClientFrameView() {
142   return new NativeFrameView(GetWidget());
145 bool NativeWidgetMac::ShouldUseNativeFrame() const {
146   return true;
149 bool NativeWidgetMac::ShouldWindowContentsBeTransparent() const {
150   // On Windows, this returns true when Aero is enabled which draws the titlebar
151   // with translucency.
152   return false;
155 void NativeWidgetMac::FrameTypeChanged() {
156   NOTIMPLEMENTED();
159 Widget* NativeWidgetMac::GetWidget() {
160   return delegate_->AsWidget();
163 const Widget* NativeWidgetMac::GetWidget() const {
164   return delegate_->AsWidget();
167 gfx::NativeView NativeWidgetMac::GetNativeView() const {
168   // Returns a BridgedContentView, unless there is no views::RootView set.
169   return [GetNativeWindow() contentView];
172 gfx::NativeWindow NativeWidgetMac::GetNativeWindow() const {
173   return bridge_ ? bridge_->ns_window() : nil;
176 Widget* NativeWidgetMac::GetTopLevelWidget() {
177   NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
178   return native_widget ? native_widget->GetWidget() : NULL;
181 const ui::Compositor* NativeWidgetMac::GetCompositor() const {
182   return bridge_ && bridge_->layer() ? bridge_->layer()->GetCompositor()
183                                      : nullptr;
186 const ui::Layer* NativeWidgetMac::GetLayer() const {
187   return bridge_ ? bridge_->layer() : nullptr;
190 void NativeWidgetMac::ReorderNativeViews() {
191   if (bridge_)
192     bridge_->SetRootView(GetWidget()->GetRootView());
195 void NativeWidgetMac::ViewRemoved(View* view) {
196   NOTIMPLEMENTED();
199 void NativeWidgetMac::SetNativeWindowProperty(const char* name, void* value) {
200   if (bridge_)
201     bridge_->SetNativeWindowProperty(name, value);
204 void* NativeWidgetMac::GetNativeWindowProperty(const char* name) const {
205   if (bridge_)
206     return bridge_->GetNativeWindowProperty(name);
208   return nullptr;
211 TooltipManager* NativeWidgetMac::GetTooltipManager() const {
212   if (bridge_)
213     return bridge_->tooltip_manager();
215   return nullptr;
218 void NativeWidgetMac::SetCapture() {
219   if (bridge_ && !bridge_->HasCapture())
220     bridge_->AcquireCapture();
223 void NativeWidgetMac::ReleaseCapture() {
224   if (bridge_)
225     bridge_->ReleaseCapture();
228 bool NativeWidgetMac::HasCapture() const {
229   return bridge_ && bridge_->HasCapture();
232 ui::InputMethod* NativeWidgetMac::GetInputMethod() {
233   return bridge_ ? bridge_->GetInputMethod() : NULL;
236 void NativeWidgetMac::CenterWindow(const gfx::Size& size) {
237   SetSize(
238       BridgedNativeWidget::GetWindowSizeForClientSize(GetNativeWindow(), size));
239   // Note that this is not the precise center of screen, but it is the standard
240   // location for windows like dialogs to appear on screen for Mac.
241   // TODO(tapted): If there is a parent window, center in that instead.
242   [GetNativeWindow() center];
245 void NativeWidgetMac::GetWindowPlacement(
246     gfx::Rect* bounds,
247     ui::WindowShowState* show_state) const {
248   *bounds = GetRestoredBounds();
249   if (IsFullscreen())
250     *show_state = ui::SHOW_STATE_FULLSCREEN;
251   else if (IsMinimized())
252     *show_state = ui::SHOW_STATE_MINIMIZED;
253   else
254     *show_state = ui::SHOW_STATE_NORMAL;
257 bool NativeWidgetMac::SetWindowTitle(const base::string16& title) {
258   NSWindow* window = GetNativeWindow();
259   NSString* current_title = [window title];
260   NSString* new_title = SysUTF16ToNSString(title);
261   if ([current_title isEqualToString:new_title])
262     return false;
264   [window setTitle:new_title];
265   return true;
268 void NativeWidgetMac::SetWindowIcons(const gfx::ImageSkia& window_icon,
269                                      const gfx::ImageSkia& app_icon) {
270   NOTIMPLEMENTED();
273 void NativeWidgetMac::InitModalType(ui::ModalType modal_type) {
274   if (modal_type == ui::MODAL_TYPE_NONE)
275     return;
277   // System modal windows not implemented (or used) on Mac.
278   DCHECK_NE(ui::MODAL_TYPE_SYSTEM, modal_type);
279   DCHECK(bridge_->parent());
280   // Everyhing happens upon show.
283 gfx::Rect NativeWidgetMac::GetWindowBoundsInScreen() const {
284   return gfx::ScreenRectFromNSRect([GetNativeWindow() frame]);
287 gfx::Rect NativeWidgetMac::GetClientAreaBoundsInScreen() const {
288   NSWindow* window = GetNativeWindow();
289   return gfx::ScreenRectFromNSRect(
290       [window contentRectForFrameRect:[window frame]]);
293 gfx::Rect NativeWidgetMac::GetRestoredBounds() const {
294   return bridge_ ? bridge_->GetRestoredBounds() : gfx::Rect();
297 void NativeWidgetMac::SetBounds(const gfx::Rect& bounds) {
298   if (bridge_)
299     bridge_->SetBounds(bounds);
302 void NativeWidgetMac::SetSize(const gfx::Size& size) {
303   // Ensure the top-left corner stays in-place (rather than the bottom-left,
304   // which -[NSWindow setContentSize:] would do).
305   SetBounds(gfx::Rect(GetWindowBoundsInScreen().origin(), size));
308 void NativeWidgetMac::StackAbove(gfx::NativeView native_view) {
309   NOTIMPLEMENTED();
312 void NativeWidgetMac::StackAtTop() {
313   NOTIMPLEMENTED();
316 void NativeWidgetMac::StackBelow(gfx::NativeView native_view) {
317   NOTIMPLEMENTED();
320 void NativeWidgetMac::SetShape(SkRegion* shape) {
321   NOTIMPLEMENTED();
324 void NativeWidgetMac::Close() {
325   if (!bridge_)
326     return;
328   NSWindow* window = GetNativeWindow();
329   if (IsWindowModalSheet()) {
330     // Sheets can't be closed normally. This starts the sheet closing. Once the
331     // sheet has finished animating, it will call sheetDidEnd: on the parent
332     // window's delegate. Note it still needs to be asynchronous, since code
333     // calling Widget::Close() doesn't expect things to be deleted upon return.
334     [NSApp performSelector:@selector(endSheet:) withObject:window afterDelay:0];
335     return;
336   }
338   // For other modal types, animate the close.
339   if (delegate_->IsModal()) {
340     [ViewsNSWindowCloseAnimator closeWindowWithAnimation:window];
341     return;
342   }
344   // Clear the view early to suppress repaints.
345   bridge_->SetRootView(NULL);
347   // Calling performClose: will momentarily highlight the close button, but
348   // AppKit will reject it if there is no close button.
349   SEL close_selector = ([window styleMask] & NSClosableWindowMask)
350                            ? @selector(performClose:)
351                            : @selector(close);
352   [window performSelector:close_selector withObject:nil afterDelay:0];
355 void NativeWidgetMac::CloseNow() {
356   if (!bridge_)
357     return;
359   // Notify observers while |bridged_| is still valid.
360   delegate_->OnNativeWidgetDestroying();
361   // Reset |bridge_| to NULL before destroying it.
362   scoped_ptr<BridgedNativeWidget> bridge(bridge_.Pass());
365 void NativeWidgetMac::Show() {
366   ShowWithWindowState(ui::SHOW_STATE_NORMAL);
369 void NativeWidgetMac::Hide() {
370   if (!bridge_)
371     return;
373   bridge_->SetVisibilityState(BridgedNativeWidget::HIDE_WINDOW);
376 void NativeWidgetMac::ShowMaximizedWithBounds(
377     const gfx::Rect& restored_bounds) {
378   NOTIMPLEMENTED();
381 void NativeWidgetMac::ShowWithWindowState(ui::WindowShowState state) {
382   if (!bridge_)
383     return;
385   switch (state) {
386     case ui::SHOW_STATE_DEFAULT:
387     case ui::SHOW_STATE_NORMAL:
388     case ui::SHOW_STATE_INACTIVE:
389       break;
390     case ui::SHOW_STATE_MINIMIZED:
391     case ui::SHOW_STATE_MAXIMIZED:
392     case ui::SHOW_STATE_FULLSCREEN:
393     case ui::SHOW_STATE_DOCKED:
394       NOTIMPLEMENTED();
395       break;
396     case ui::SHOW_STATE_END:
397       NOTREACHED();
398       break;
399   }
400   bridge_->SetVisibilityState(state == ui::SHOW_STATE_INACTIVE
401       ? BridgedNativeWidget::SHOW_INACTIVE
402       : BridgedNativeWidget::SHOW_AND_ACTIVATE_WINDOW);
405 bool NativeWidgetMac::IsVisible() const {
406   return bridge_ && bridge_->window_visible();
409 void NativeWidgetMac::Activate() {
410   if (!bridge_)
411     return;
413   bridge_->SetVisibilityState(BridgedNativeWidget::SHOW_AND_ACTIVATE_WINDOW);
416 void NativeWidgetMac::Deactivate() {
417   NOTIMPLEMENTED();
420 bool NativeWidgetMac::IsActive() const {
421   return [GetNativeWindow() isKeyWindow];
424 void NativeWidgetMac::SetAlwaysOnTop(bool always_on_top) {
425   gfx::SetNSWindowAlwaysOnTop(GetNativeWindow(), always_on_top);
428 bool NativeWidgetMac::IsAlwaysOnTop() const {
429   return gfx::IsNSWindowAlwaysOnTop(GetNativeWindow());
432 void NativeWidgetMac::SetVisibleOnAllWorkspaces(bool always_visible) {
433   gfx::SetNSWindowVisibleOnAllWorkspaces(GetNativeWindow(), always_visible);
436 void NativeWidgetMac::Maximize() {
437   NOTIMPLEMENTED();  // See IsMaximized().
440 void NativeWidgetMac::Minimize() {
441   NSWindow* window = GetNativeWindow();
442   // Calling performMiniaturize: will momentarily highlight the button, but
443   // AppKit will reject it if there is no miniaturize button.
444   if ([window styleMask] & NSMiniaturizableWindowMask)
445     [window performMiniaturize:nil];
446   else
447     [window miniaturize:nil];
450 bool NativeWidgetMac::IsMaximized() const {
451   // The window frame isn't altered on Mac unless going fullscreen. The green
452   // "+" button just makes the window bigger. So, always false.
453   return false;
456 bool NativeWidgetMac::IsMinimized() const {
457   return [GetNativeWindow() isMiniaturized];
460 void NativeWidgetMac::Restore() {
461   SetFullscreen(false);
462   [GetNativeWindow() deminiaturize:nil];
465 void NativeWidgetMac::SetFullscreen(bool fullscreen) {
466   if (!bridge_ || fullscreen == IsFullscreen())
467     return;
469   bridge_->ToggleDesiredFullscreenState();
472 bool NativeWidgetMac::IsFullscreen() const {
473   return bridge_ && bridge_->target_fullscreen_state();
476 void NativeWidgetMac::SetOpacity(unsigned char opacity) {
477   NOTIMPLEMENTED();
480 void NativeWidgetMac::SetUseDragFrame(bool use_drag_frame) {
481   NOTIMPLEMENTED();
484 void NativeWidgetMac::FlashFrame(bool flash_frame) {
485   NOTIMPLEMENTED();
488 void NativeWidgetMac::RunShellDrag(View* view,
489                                    const ui::OSExchangeData& data,
490                                    const gfx::Point& location,
491                                    int operation,
492                                    ui::DragDropTypes::DragEventSource source) {
493   NOTIMPLEMENTED();
496 void NativeWidgetMac::SchedulePaintInRect(const gfx::Rect& rect) {
497   // TODO(tapted): This should use setNeedsDisplayInRect:, once the coordinate
498   // system of |rect| has been converted.
499   [GetNativeView() setNeedsDisplay:YES];
500   if (bridge_ && bridge_->layer())
501     bridge_->layer()->SchedulePaint(rect);
504 void NativeWidgetMac::SetCursor(gfx::NativeCursor cursor) {
505   if (bridge_)
506     bridge_->SetCursor(cursor);
509 bool NativeWidgetMac::IsMouseEventsEnabled() const {
510   // On platforms with touch, mouse events get disabled and calls to this method
511   // can affect hover states. Since there is no touch on desktop Mac, this is
512   // always true. Touch on Mac is tracked in http://crbug.com/445520.
513   return true;
516 void NativeWidgetMac::ClearNativeFocus() {
517   // To quote DesktopWindowTreeHostX11, "This method is weird and misnamed."
518   // The goal is to set focus to the content window, thereby removing focus from
519   // any NSView in the window that doesn't belong to toolkit-views.
520   [GetNativeWindow() makeFirstResponder:GetNativeView()];
523 gfx::Rect NativeWidgetMac::GetWorkAreaBoundsInScreen() const {
524   return gfx::ScreenRectFromNSRect([[GetNativeWindow() screen] visibleFrame]);
527 Widget::MoveLoopResult NativeWidgetMac::RunMoveLoop(
528     const gfx::Vector2d& drag_offset,
529     Widget::MoveLoopSource source,
530     Widget::MoveLoopEscapeBehavior escape_behavior) {
531   NOTIMPLEMENTED();
532   return Widget::MOVE_LOOP_CANCELED;
535 void NativeWidgetMac::EndMoveLoop() {
536   NOTIMPLEMENTED();
539 void NativeWidgetMac::SetVisibilityChangedAnimationsEnabled(bool value) {
540   NOTIMPLEMENTED();
543 void NativeWidgetMac::SetVisibilityAnimationDuration(
544     const base::TimeDelta& duration) {
545   NOTIMPLEMENTED();
548 void NativeWidgetMac::SetVisibilityAnimationTransition(
549     Widget::VisibilityTransition transition) {
550   NOTIMPLEMENTED();
553 ui::NativeTheme* NativeWidgetMac::GetNativeTheme() const {
554   return ui::NativeTheme::instance();
557 void NativeWidgetMac::OnRootViewLayout() {
558   // Ensure possible changes to the non-client view (e.g. Minimum/Maximum size)
559   // propagate through to the NSWindow properties.
560   OnSizeConstraintsChanged();
563 bool NativeWidgetMac::IsTranslucentWindowOpacitySupported() const {
564   return false;
567 void NativeWidgetMac::OnSizeConstraintsChanged() {
568   bridge_->OnSizeConstraintsChanged();
571 void NativeWidgetMac::RepostNativeEvent(gfx::NativeEvent native_event) {
572   NOTIMPLEMENTED();
575 ////////////////////////////////////////////////////////////////////////////////
576 // NativeWidgetMac, protected:
578 NativeWidgetMacNSWindow* NativeWidgetMac::CreateNSWindow(
579     const Widget::InitParams& params) {
580   return [[[NativeWidgetMacNSWindow alloc]
581       initWithContentRect:ui::kWindowSizeDeterminedLater
582                 styleMask:StyleMaskForParams(params)
583                   backing:NSBackingStoreBuffered
584                     defer:NO] autorelease];
587 ////////////////////////////////////////////////////////////////////////////////
588 // Widget, public:
590 bool Widget::ConvertRect(const Widget* source,
591                          const Widget* target,
592                          gfx::Rect* rect) {
593   return false;
596 namespace internal {
598 ////////////////////////////////////////////////////////////////////////////////
599 // internal::NativeWidgetPrivate, public:
601 // static
602 NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
603     internal::NativeWidgetDelegate* delegate) {
604   return new NativeWidgetMac(delegate);
607 // static
608 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
609     gfx::NativeView native_view) {
610   return GetNativeWidgetForNativeWindow([native_view window]);
613 // static
614 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
615     gfx::NativeWindow native_window) {
616   id<NSWindowDelegate> window_delegate = [native_window delegate];
617   if ([window_delegate respondsToSelector:@selector(nativeWidgetMac)]) {
618     ViewsNSWindowDelegate* delegate =
619         base::mac::ObjCCastStrict<ViewsNSWindowDelegate>(window_delegate);
620     return [delegate nativeWidgetMac];
621   }
622   return NULL;  // Not created by NativeWidgetMac.
625 // static
626 NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
627     gfx::NativeView native_view) {
628   BridgedNativeWidget* bridge =
629       NativeWidgetMac::GetBridgeForNativeWindow([native_view window]);
630   if (!bridge)
631     return nullptr;
633   NativeWidgetPrivate* ancestor =
634       bridge->parent() ? GetTopLevelNativeWidget(
635                              [bridge->parent()->GetNSWindow() contentView])
636                        : nullptr;
637   return ancestor ? ancestor : bridge->native_widget_mac();
640 // static
641 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view,
642                                              Widget::Widgets* children) {
643   BridgedNativeWidget* bridge =
644       NativeWidgetMac::GetBridgeForNativeWindow([native_view window]);
645   if (!bridge)
646     return;
648   // If |native_view| is a subview of the contentView, it will share an
649   // NSWindow, but will itself be a native child of the Widget. That is, adding
650   // bridge->..->GetWidget() to |children| would be adding the _parent_ of
651   // |native_view|, not the Widget for |native_view|. |native_view| doesn't have
652   // a corresponding Widget of its own in this case (and so can't have Widget
653   // children of its own on Mac).
654   if (bridge->ns_view() != native_view)
655     return;
657   // Code expects widget for |native_view| to be added to |children|.
658   if (bridge->native_widget_mac()->GetWidget())
659     children->insert(bridge->native_widget_mac()->GetWidget());
661   for (BridgedNativeWidget* child : bridge->child_windows())
662     GetAllChildWidgets(child->ns_view(), children);
665 // static
666 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view,
667                                              Widget::Widgets* owned) {
668   NOTIMPLEMENTED();
671 // static
672 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
673                                              gfx::NativeView new_parent) {
674   BridgedNativeWidget* bridge =
675       NativeWidgetMac::GetBridgeForNativeWindow([native_view window]);
676   if (bridge && bridge->parent() &&
677       bridge->parent()->GetNSWindow() == [new_parent window])
678     return;  // Nothing to do.
680   // Not supported. See http://crbug.com/514920.
681   NOTREACHED();
684 // static
685 bool NativeWidgetPrivate::IsMouseButtonDown() {
686   return [NSEvent pressedMouseButtons] != 0;
689 // static
690 gfx::FontList NativeWidgetPrivate::GetWindowTitleFontList() {
691   NOTIMPLEMENTED();
692   return gfx::FontList();
695 }  // namespace internal
696 }  // namespace views
698 @implementation ViewsNSWindowCloseAnimator
700 - (id)initWithWindow:(NSWindow*)window {
701   if ((self = [super init])) {
702     window_.reset([window retain]);
703     animation_.reset(
704         [[ConstrainedWindowAnimationHide alloc] initWithWindow:window]);
705     [animation_ setDelegate:self];
706     [animation_ setAnimationBlockingMode:NSAnimationNonblocking];
707     [animation_ startAnimation];
708   }
709   return self;
712 + (void)closeWindowWithAnimation:(NSWindow*)window {
713   [[ViewsNSWindowCloseAnimator alloc] initWithWindow:window];
716 - (void)animationDidEnd:(NSAnimation*)animation {
717   [window_ close];
718   [animation_ setDelegate:nil];
719   [self release];
722 @end