Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: ui/views/cocoa/bridged_native_widget.mm

Issue 927233003: MacViews: Fix positioning of top-level Widgets with parents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@20150129-MacViews-Bringup5
Patch Set: Use kWindowSizeDeterminedLater Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 20 matching lines...) Expand all
31 31
32 int kWindowPropertiesKey; 32 int kWindowPropertiesKey;
33 33
34 float GetDeviceScaleFactorFromView(NSView* view) { 34 float GetDeviceScaleFactorFromView(NSView* view) {
35 gfx::Display display = 35 gfx::Display display =
36 gfx::Screen::GetScreenFor(view)->GetDisplayNearestWindow(view); 36 gfx::Screen::GetScreenFor(view)->GetDisplayNearestWindow(view);
37 DCHECK(display.is_valid()); 37 DCHECK(display.is_valid());
38 return display.device_scale_factor(); 38 return display.device_scale_factor();
39 } 39 }
40 40
41 // Returns true if bounds passed to window in SetBounds should be treated as
42 // though they are in screen coordinates.
43 bool PositionWindowInScreenCoordinates(views::Widget* widget,
44 views::Widget::InitParams::Type type) {
45 // Replicate the logic in desktop_aura/desktop_screen_position_client.cc.
46 if (type == views::Widget::InitParams::TYPE_POPUP)
Andre 2015/02/23 18:27:08 The aura version of this checks for ui::wm::WINDOW
tapted 2015/02/24 00:14:32 ooh - good catch! Fixed. used GetAuraWindowTypeFo
47 return true;
48
49 return widget && widget->is_top_level();
50 }
51
41 } // namespace 52 } // namespace
42 53
43 namespace views { 54 namespace views {
44 55
45 BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent) 56 BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent)
46 : native_widget_mac_(parent), 57 : native_widget_mac_(parent),
47 focus_manager_(NULL), 58 focus_manager_(nullptr),
59 widget_type_(Widget::InitParams::TYPE_WINDOW), // Updated in Init().
48 parent_(nullptr), 60 parent_(nullptr),
49 target_fullscreen_state_(false), 61 target_fullscreen_state_(false),
50 in_fullscreen_transition_(false), 62 in_fullscreen_transition_(false),
51 window_visible_(false), 63 window_visible_(false),
52 wants_to_be_visible_(false) { 64 wants_to_be_visible_(false) {
53 DCHECK(parent); 65 DCHECK(parent);
54 window_delegate_.reset( 66 window_delegate_.reset(
55 [[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]); 67 [[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]);
56 } 68 }
57 69
58 BridgedNativeWidget::~BridgedNativeWidget() { 70 BridgedNativeWidget::~BridgedNativeWidget() {
59 RemoveOrDestroyChildren(); 71 RemoveOrDestroyChildren();
60 DCHECK(child_windows_.empty()); 72 DCHECK(child_windows_.empty());
61 SetFocusManager(NULL); 73 SetFocusManager(NULL);
62 SetRootView(NULL); 74 SetRootView(NULL);
63 DestroyCompositor(); 75 DestroyCompositor();
64 if ([window_ delegate]) { 76 if ([window_ delegate]) {
65 // If the delegate is still set, it means OnWindowWillClose has not been 77 // If the delegate is still set, it means OnWindowWillClose has not been
66 // called and the window is still open. Calling -[NSWindow close] will 78 // called and the window is still open. Calling -[NSWindow close] will
67 // synchronously call OnWindowWillClose and notify NativeWidgetMac. 79 // synchronously call OnWindowWillClose and notify NativeWidgetMac.
68 [window_ close]; 80 [window_ close];
69 } 81 }
70 DCHECK(![window_ delegate]); 82 DCHECK(![window_ delegate]);
71 } 83 }
72 84
73 void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window, 85 void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window,
74 const Widget::InitParams& params) { 86 const Widget::InitParams& params) {
87 widget_type_ = params.type;
88
75 DCHECK(!window_); 89 DCHECK(!window_);
76 window_.swap(window); 90 window_.swap(window);
77 [window_ setDelegate:window_delegate_]; 91 [window_ setDelegate:window_delegate_];
78 92
79 // Register for application hide notifications so that visibility can be 93 // Register for application hide notifications so that visibility can be
80 // properly tracked. This is not done in the delegate so that the lifetime is 94 // properly tracked. This is not done in the delegate so that the lifetime is
81 // tied to the C++ object, rather than the delegate (which may be reference 95 // tied to the C++ object, rather than the delegate (which may be reference
82 // counted). This is required since the application hides do not send an 96 // counted). This is required since the application hides do not send an
83 // orderOut: to individual windows. Unhide, however, does send an order 97 // orderOut: to individual windows. Unhide, however, does send an order
84 // message. 98 // message.
(...skipping 14 matching lines...) Expand all
99 BridgedNativeWidget* parent = 113 BridgedNativeWidget* parent =
100 NativeWidgetMac::GetBridgeForNativeWindow([params.parent window]); 114 NativeWidgetMac::GetBridgeForNativeWindow([params.parent window]);
101 // The parent could be an NSWindow without an associated Widget. That could 115 // The parent could be an NSWindow without an associated Widget. That could
102 // work by observing NSWindowWillCloseNotification, but for now it's not 116 // work by observing NSWindowWillCloseNotification, but for now it's not
103 // supported, and there might not be a use-case for that. 117 // supported, and there might not be a use-case for that.
104 CHECK(parent); 118 CHECK(parent);
105 parent_ = parent; 119 parent_ = parent;
106 parent->child_windows_.push_back(this); 120 parent->child_windows_.push_back(this);
107 } 121 }
108 122
123 // Set a meaningful initial bounds. Note that except for frameless widgets
124 // with no WidgetDelegate, the bounds will be set again by Widget after
125 // initializing the non-client view. In the former case, if bounds were not
126 // set at all, the creator of the Widget is expected to call SetBounds()
127 // before calling Widget::Show() to avoid a kWindowSizeDeterminedLater-sized
128 // (i.e. 1x1) window appearing.
129 if (!params.bounds.IsEmpty()) {
130 SetBounds(params.bounds);
131 } else {
132 // If a position is set, but no size, complain. Otherwise, a 1x1 window
133 // would appear there, which might be unexpected.
134 DCHECK(params.bounds.origin().IsOrigin())
135 << "Zero-sized windows not supported on Mac.";
136 }
137
109 // Widgets for UI controls (usually layered above web contents) start visible. 138 // Widgets for UI controls (usually layered above web contents) start visible.
110 if (params.type == Widget::InitParams::TYPE_CONTROL) 139 if (params.type == Widget::InitParams::TYPE_CONTROL)
111 SetVisibilityState(SHOW_INACTIVE); 140 SetVisibilityState(SHOW_INACTIVE);
112 } 141 }
113 142
114 void BridgedNativeWidget::SetFocusManager(FocusManager* focus_manager) { 143 void BridgedNativeWidget::SetFocusManager(FocusManager* focus_manager) {
115 if (focus_manager_ == focus_manager) 144 if (focus_manager_ == focus_manager)
116 return; 145 return;
117 146
118 if (focus_manager_) 147 if (focus_manager_)
119 focus_manager_->RemoveFocusChangeListener(this); 148 focus_manager_->RemoveFocusChangeListener(this);
120 149
121 if (focus_manager) 150 if (focus_manager)
122 focus_manager->AddFocusChangeListener(this); 151 focus_manager->AddFocusChangeListener(this);
123 152
124 focus_manager_ = focus_manager; 153 focus_manager_ = focus_manager;
125 } 154 }
126 155
127 void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) { 156 void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) {
157 // A contentRect with zero width or height is a banned practice in ChromeMac,
158 // due to unpredictable OSX treatment.
159 DCHECK(!new_bounds.IsEmpty()) << "Zero-sized windows not supported on Mac";
160
128 gfx::Rect actual_new_bounds(new_bounds); 161 gfx::Rect actual_new_bounds(new_bounds);
129 if (parent_) 162
163 if (parent_ &&
164 !PositionWindowInScreenCoordinates(native_widget_mac_->GetWidget(),
165 widget_type_))
130 actual_new_bounds.Offset(parent_->GetRestoredBounds().OffsetFromOrigin()); 166 actual_new_bounds.Offset(parent_->GetRestoredBounds().OffsetFromOrigin());
131 167
132 [window_ setFrame:gfx::ScreenRectToNSRect(actual_new_bounds) 168 [window_ setFrame:gfx::ScreenRectToNSRect(actual_new_bounds)
133 display:YES 169 display:YES
134 animate:NO]; 170 animate:NO];
135 } 171 }
136 172
137 void BridgedNativeWidget::SetRootView(views::View* view) { 173 void BridgedNativeWidget::SetRootView(views::View* view) {
138 if (view == [bridged_view_ hostedView]) 174 if (view == [bridged_view_ hostedView])
139 return; 175 return;
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 window_, &kWindowPropertiesKey); 731 window_, &kWindowPropertiesKey);
696 if (!properties) { 732 if (!properties) {
697 properties = [NSMutableDictionary dictionary]; 733 properties = [NSMutableDictionary dictionary];
698 objc_setAssociatedObject(window_, &kWindowPropertiesKey, 734 objc_setAssociatedObject(window_, &kWindowPropertiesKey,
699 properties, OBJC_ASSOCIATION_RETAIN); 735 properties, OBJC_ASSOCIATION_RETAIN);
700 } 736 }
701 return properties; 737 return properties;
702 } 738 }
703 739
704 } // namespace views 740 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/cocoa/bridged_native_widget_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698