| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ui/views/cocoa/bridged_native_widget.h" | 5 #import "ui/views/cocoa/bridged_native_widget.h" |
| 6 | 6 |
| 7 #import <objc/runtime.h> | 7 #import <objc/runtime.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 [[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]); | 80 [[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]); |
| 81 } | 81 } |
| 82 | 82 |
| 83 BridgedNativeWidget::~BridgedNativeWidget() { | 83 BridgedNativeWidget::~BridgedNativeWidget() { |
| 84 RemoveOrDestroyChildren(); | 84 RemoveOrDestroyChildren(); |
| 85 DCHECK(child_windows_.empty()); | 85 DCHECK(child_windows_.empty()); |
| 86 SetFocusManager(NULL); | 86 SetFocusManager(NULL); |
| 87 SetRootView(NULL); | 87 SetRootView(NULL); |
| 88 DestroyCompositor(); | 88 DestroyCompositor(); |
| 89 if ([window_ delegate]) { | 89 if ([window_ delegate]) { |
| 90 // If the delegate is still set on a modal dialog, it means it was not |
| 91 // closed via [NSApplication endSheet:]. This is probably OK if the widget |
| 92 // was never shown. But Cocoa ignores close() calls on open sheets. Calling |
| 93 // endSheet: here would work, but it messes up assumptions elsewhere. E.g. |
| 94 // DialogClientView assumes its delegate is alive when closing, which isn't |
| 95 // true after endSheet: synchronously calls OnNativeWidgetDestroyed(). |
| 96 // So ban it. Modal dialogs should be closed via Widget::Close(). |
| 97 DCHECK(!native_widget_mac_->GetWidget()->IsModal()); |
| 98 |
| 90 // If the delegate is still set, it means OnWindowWillClose has not been | 99 // If the delegate is still set, it means OnWindowWillClose has not been |
| 91 // called and the window is still open. Calling -[NSWindow close] will | 100 // called and the window is still open. Calling -[NSWindow close] will |
| 92 // synchronously call OnWindowWillClose and notify NativeWidgetMac. | 101 // synchronously call OnWindowWillClose and notify NativeWidgetMac. |
| 93 [window_ close]; | 102 [window_ close]; |
| 94 } | 103 } |
| 95 DCHECK(![window_ delegate]); | 104 DCHECK(![window_ delegate]); |
| 96 } | 105 } |
| 97 | 106 |
| 98 void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window, | 107 void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window, |
| 99 const Widget::InitParams& params) { | 108 const Widget::InitParams& params) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 focus_manager->AddFocusChangeListener(this); | 182 focus_manager->AddFocusChangeListener(this); |
| 174 | 183 |
| 175 focus_manager_ = focus_manager; | 184 focus_manager_ = focus_manager; |
| 176 } | 185 } |
| 177 | 186 |
| 178 void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) { | 187 void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) { |
| 179 // A contentRect with zero width or height is a banned practice in ChromeMac, | 188 // A contentRect with zero width or height is a banned practice in ChromeMac, |
| 180 // due to unpredictable OSX treatment. | 189 // due to unpredictable OSX treatment. |
| 181 DCHECK(!new_bounds.IsEmpty()) << "Zero-sized windows not supported on Mac"; | 190 DCHECK(!new_bounds.IsEmpty()) << "Zero-sized windows not supported on Mac"; |
| 182 | 191 |
| 192 if (native_widget_mac_->GetWidget()->IsModal()) { |
| 193 // Modal dialogs are positioned by Cocoa. Just update the size. |
| 194 [window_ |
| 195 setContentSize:NSMakeSize(new_bounds.width(), new_bounds.height())]; |
| 196 return; |
| 197 } |
| 198 |
| 183 gfx::Rect actual_new_bounds(new_bounds); | 199 gfx::Rect actual_new_bounds(new_bounds); |
| 184 | 200 |
| 185 if (parent_ && | 201 if (parent_ && |
| 186 !PositionWindowInScreenCoordinates(native_widget_mac_->GetWidget(), | 202 !PositionWindowInScreenCoordinates(native_widget_mac_->GetWidget(), |
| 187 widget_type_)) | 203 widget_type_)) |
| 188 actual_new_bounds.Offset(parent_->GetRestoredBounds().OffsetFromOrigin()); | 204 actual_new_bounds.Offset(parent_->GetRestoredBounds().OffsetFromOrigin()); |
| 189 | 205 |
| 190 [window_ setFrame:gfx::ScreenRectToNSRect(actual_new_bounds) | 206 [window_ setFrame:gfx::ScreenRectToNSRect(actual_new_bounds) |
| 191 display:YES | 207 display:YES |
| 192 animate:NO]; | 208 animate:NO]; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 DCHECK(wants_to_be_visible_); | 248 DCHECK(wants_to_be_visible_); |
| 233 | 249 |
| 234 // If there's a hidden ancestor, return and wait for it to become visible. | 250 // If there's a hidden ancestor, return and wait for it to become visible. |
| 235 for (BridgedNativeWidget* ancestor = parent(); | 251 for (BridgedNativeWidget* ancestor = parent(); |
| 236 ancestor; | 252 ancestor; |
| 237 ancestor = ancestor->parent()) { | 253 ancestor = ancestor->parent()) { |
| 238 if (!ancestor->window_visible_) | 254 if (!ancestor->window_visible_) |
| 239 return; | 255 return; |
| 240 } | 256 } |
| 241 | 257 |
| 258 if (native_widget_mac_->GetWidget()->IsModal()) { |
| 259 NSWindow* parent_window = parent_->ns_window(); |
| 260 DCHECK(parent_window); |
| 261 |
| 262 [NSApp beginSheet:window_ |
| 263 modalForWindow:parent_window |
| 264 modalDelegate:[window_ delegate] |
| 265 didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) |
| 266 contextInfo:nullptr]; |
| 267 return; |
| 268 } |
| 269 |
| 242 if (new_state == SHOW_AND_ACTIVATE_WINDOW) { | 270 if (new_state == SHOW_AND_ACTIVATE_WINDOW) { |
| 243 [window_ makeKeyAndOrderFront:nil]; | 271 [window_ makeKeyAndOrderFront:nil]; |
| 244 [NSApp activateIgnoringOtherApps:YES]; | 272 [NSApp activateIgnoringOtherApps:YES]; |
| 245 } else { | 273 } else { |
| 246 // ui::SHOW_STATE_INACTIVE is typically used to avoid stealing focus from a | 274 // ui::SHOW_STATE_INACTIVE is typically used to avoid stealing focus from a |
| 247 // parent window. So, if there's a parent, order above that. Otherwise, this | 275 // parent window. So, if there's a parent, order above that. Otherwise, this |
| 248 // will order above all windows at the same level. | 276 // will order above all windows at the same level. |
| 249 NSInteger parent_window_number = 0; | 277 NSInteger parent_window_number = 0; |
| 250 if (parent()) | 278 if (parent()) |
| 251 parent_window_number = [parent()->ns_window() windowNumber]; | 279 parent_window_number = [parent()->ns_window() windowNumber]; |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 if (layer()) | 471 if (layer()) |
| 444 UpdateLayerProperties(); | 472 UpdateLayerProperties(); |
| 445 } | 473 } |
| 446 | 474 |
| 447 void BridgedNativeWidget::OnWindowKeyStatusChangedTo(bool is_key) { | 475 void BridgedNativeWidget::OnWindowKeyStatusChangedTo(bool is_key) { |
| 448 Widget* widget = native_widget_mac()->GetWidget(); | 476 Widget* widget = native_widget_mac()->GetWidget(); |
| 449 widget->OnNativeWidgetActivationChanged(is_key); | 477 widget->OnNativeWidgetActivationChanged(is_key); |
| 450 // The contentView is the BridgedContentView hosting the views::RootView. The | 478 // The contentView is the BridgedContentView hosting the views::RootView. The |
| 451 // focus manager will already know if a native subview has focus. | 479 // focus manager will already know if a native subview has focus. |
| 452 if ([window_ contentView] == [window_ firstResponder]) { | 480 if ([window_ contentView] == [window_ firstResponder]) { |
| 453 if (is_key) | 481 if (is_key) { |
| 482 widget->OnNativeFocus(); |
| 454 widget->GetFocusManager()->RestoreFocusedView(); | 483 widget->GetFocusManager()->RestoreFocusedView(); |
| 455 else | 484 } else { |
| 485 widget->OnNativeBlur(); |
| 456 widget->GetFocusManager()->StoreFocusedView(true); | 486 widget->GetFocusManager()->StoreFocusedView(true); |
| 487 } |
| 457 } | 488 } |
| 458 } | 489 } |
| 459 | 490 |
| 460 InputMethod* BridgedNativeWidget::CreateInputMethod() { | 491 InputMethod* BridgedNativeWidget::CreateInputMethod() { |
| 461 if (switches::IsTextInputFocusManagerEnabled()) | 492 if (switches::IsTextInputFocusManagerEnabled()) |
| 462 return new NullInputMethod(); | 493 return new NullInputMethod(); |
| 463 | 494 |
| 464 return new InputMethodBridge(this, GetHostInputMethod(), true); | 495 return new InputMethodBridge(this, GetHostInputMethod(), true); |
| 465 } | 496 } |
| 466 | 497 |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 window_, &kWindowPropertiesKey); | 784 window_, &kWindowPropertiesKey); |
| 754 if (!properties) { | 785 if (!properties) { |
| 755 properties = [NSMutableDictionary dictionary]; | 786 properties = [NSMutableDictionary dictionary]; |
| 756 objc_setAssociatedObject(window_, &kWindowPropertiesKey, | 787 objc_setAssociatedObject(window_, &kWindowPropertiesKey, |
| 757 properties, OBJC_ASSOCIATION_RETAIN); | 788 properties, OBJC_ASSOCIATION_RETAIN); |
| 758 } | 789 } |
| 759 return properties; | 790 return properties; |
| 760 } | 791 } |
| 761 | 792 |
| 762 } // namespace views | 793 } // namespace views |
| OLD | NEW |