OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 #include "ash/mus/non_client_frame_controller.h" | 5 #include "ash/mus/non_client_frame_controller.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "ash/common/ash_constants.h" | 13 #include "ash/common/ash_constants.h" |
14 #include "ash/common/ash_layout_constants.h" | 14 #include "ash/common/ash_layout_constants.h" |
15 #include "ash/common/frame/custom_frame_view_ash.h" | 15 #include "ash/common/frame/custom_frame_view_ash.h" |
16 #include "ash/common/wm/panels/panel_frame_view.h" | 16 #include "ash/common/wm/panels/panel_frame_view.h" |
17 #include "ash/mus/bridge/wm_window_mus.h" | 17 #include "ash/mus/bridge/wm_window_mus.h" |
18 #include "ash/mus/frame/custom_frame_view_mus.h" | 18 #include "ash/mus/frame/custom_frame_view_mus.h" |
19 #include "ash/mus/frame/detached_title_area_renderer.h" | 19 #include "ash/mus/frame/detached_title_area_renderer.h" |
20 #include "ash/mus/move_event_handler.h" | 20 #include "ash/mus/move_event_handler.h" |
21 #include "ash/mus/property_util.h" | 21 #include "ash/mus/property_util.h" |
22 #include "ash/mus/shadow.h" | 22 #include "ash/mus/shadow.h" |
23 #include "ash/mus/window_manager.h" | |
24 #include "ash/mus/window_properties.h" | |
23 #include "ash/shared/immersive_fullscreen_controller_delegate.h" | 25 #include "ash/shared/immersive_fullscreen_controller_delegate.h" |
24 #include "base/macros.h" | 26 #include "base/macros.h" |
27 #include "base/memory/ptr_util.h" | |
25 #include "base/strings/utf_string_conversions.h" | 28 #include "base/strings/utf_string_conversions.h" |
26 #include "services/ui/public/cpp/property_type_converters.h" | |
27 #include "services/ui/public/cpp/window.h" | |
28 #include "services/ui/public/cpp/window_manager_delegate.h" | |
29 #include "services/ui/public/cpp/window_property.h" | |
30 #include "services/ui/public/cpp/window_tree_client.h" | |
31 #include "services/ui/public/interfaces/window_manager.mojom.h" | 29 #include "services/ui/public/interfaces/window_manager.mojom.h" |
32 #include "ui/aura/layout_manager.h" | 30 #include "ui/aura/client/aura_constants.h" |
31 #include "ui/aura/mus/property_converter.h" | |
32 #include "ui/aura/mus/property_utils.h" | |
33 #include "ui/aura/mus/window_manager_delegate.h" | |
34 #include "ui/aura/mus/window_port_mus.h" | |
33 #include "ui/aura/window.h" | 35 #include "ui/aura/window.h" |
34 #include "ui/aura/window_tree_host.h" | 36 #include "ui/aura/window_property.h" |
35 #include "ui/base/hit_test.h" | 37 #include "ui/base/hit_test.h" |
36 #include "ui/compositor/layer.h" | 38 #include "ui/compositor/layer.h" |
37 #include "ui/gfx/geometry/vector2d.h" | 39 #include "ui/gfx/geometry/vector2d.h" |
38 #include "ui/views/mus/native_widget_mus.h" | 40 #include "ui/views/widget/native_widget_aura.h" |
39 #include "ui/views/widget/widget.h" | 41 #include "ui/views/widget/widget.h" |
40 | 42 |
43 DECLARE_WINDOW_PROPERTY_TYPE(ash::mus::NonClientFrameController*); | |
44 | |
41 namespace ash { | 45 namespace ash { |
42 namespace mus { | 46 namespace mus { |
43 namespace { | 47 namespace { |
44 | 48 |
45 // LayoutManager associated with the window created by WindowTreeHost. Resizes | 49 DEFINE_WINDOW_PROPERTY_KEY(NonClientFrameController*, |
46 // all children of the parent to match the bounds of the parent. Additionally | 50 kNonClientFrameControllerKey, |
47 // handles sizing of a Shadow. | 51 nullptr); |
48 class ContentWindowLayoutManager : public aura::LayoutManager { | |
49 public: | |
50 ContentWindowLayoutManager(aura::Window* window, Shadow* shadow) | |
51 : window_(window), shadow_(shadow) { | |
52 OnWindowResized(); | |
53 } | |
54 ~ContentWindowLayoutManager() override {} | |
55 | |
56 private: | |
57 // Bounds for child windows. | |
58 gfx::Rect child_bounds() const { | |
59 return gfx::Rect(0, 0, window_->bounds().size().width(), | |
60 window_->bounds().size().height()); | |
61 } | |
62 | |
63 void UpdateChildBounds(aura::Window* child) { | |
64 child->SetBounds(child_bounds()); | |
65 } | |
66 | |
67 // aura::LayoutManager: | |
68 void OnWindowResized() override { | |
69 for (aura::Window* child : window_->children()) | |
70 UpdateChildBounds(child); | |
71 // Shadow takes care of resizing the layer appropriately. | |
72 if (shadow_) | |
73 shadow_->SetContentBounds(child_bounds()); | |
74 } | |
75 void OnWindowAddedToLayout(aura::Window* child) override { | |
76 UpdateChildBounds(child); | |
77 } | |
78 void OnWillRemoveWindowFromLayout(aura::Window* child) override {} | |
79 void OnWindowRemovedFromLayout(aura::Window* child) override {} | |
80 void OnChildWindowVisibilityChanged(aura::Window* child, | |
81 bool visible) override {} | |
82 void SetChildBounds(aura::Window* child, | |
83 const gfx::Rect& requested_bounds) override { | |
84 SetChildBoundsDirect(child, requested_bounds); | |
85 } | |
86 | |
87 aura::Window* window_; | |
88 Shadow* shadow_; | |
89 | |
90 DISALLOW_COPY_AND_ASSIGN(ContentWindowLayoutManager); | |
91 }; | |
92 | 52 |
93 // This class supports draggable app windows that paint their own custom frames. | 53 // This class supports draggable app windows that paint their own custom frames. |
94 // It uses empty insets, doesn't paint anything, and hit tests return HTCAPTION. | 54 // It uses empty insets, doesn't paint anything, and hit tests return HTCAPTION. |
95 class EmptyDraggableNonClientFrameView : public views::NonClientFrameView { | 55 class EmptyDraggableNonClientFrameView : public views::NonClientFrameView { |
96 public: | 56 public: |
97 EmptyDraggableNonClientFrameView() {} | 57 EmptyDraggableNonClientFrameView() {} |
98 ~EmptyDraggableNonClientFrameView() override {} | 58 ~EmptyDraggableNonClientFrameView() override {} |
99 | 59 |
100 // views::NonClientFrameView: | 60 // views::NonClientFrameView: |
101 gfx::Rect GetBoundsForClientView() const override { return bounds(); } | 61 gfx::Rect GetBoundsForClientView() const override { return bounds(); } |
102 gfx::Rect GetWindowBoundsForClientBounds( | 62 gfx::Rect GetWindowBoundsForClientBounds( |
103 const gfx::Rect& client_bounds) const override { | 63 const gfx::Rect& client_bounds) const override { |
104 return bounds(); | 64 return bounds(); |
105 } | 65 } |
106 int NonClientHitTest(const gfx::Point& point) override { return HTCAPTION; } | 66 int NonClientHitTest(const gfx::Point& point) override { return HTCAPTION; } |
107 void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {} | 67 void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {} |
108 void ResetWindowControls() override {} | 68 void ResetWindowControls() override {} |
109 void UpdateWindowIcon() override {} | 69 void UpdateWindowIcon() override {} |
110 void UpdateWindowTitle() override {} | 70 void UpdateWindowTitle() override {} |
111 void SizeConstraintsChanged() override {} | 71 void SizeConstraintsChanged() override {} |
112 | 72 |
113 private: | 73 private: |
114 DISALLOW_COPY_AND_ASSIGN(EmptyDraggableNonClientFrameView); | 74 DISALLOW_COPY_AND_ASSIGN(EmptyDraggableNonClientFrameView); |
115 }; | 75 }; |
116 | 76 |
117 // Creates a ui::Window to host the top container when in immersive mode. The | 77 // Creates a Window to host the top container when in immersive mode. The |
118 // top container contains a DetachedTitleAreaRenderer, which handles drawing and | 78 // top container contains a DetachedTitleAreaRenderer, which handles drawing and |
119 // events. | 79 // events. |
120 class ImmersiveFullscreenControllerDelegateMus | 80 class ImmersiveFullscreenControllerDelegateMus |
121 : public ImmersiveFullscreenControllerDelegate, | 81 : public ImmersiveFullscreenControllerDelegate, |
122 public DetachedTitleAreaRendererHost { | 82 public DetachedTitleAreaRendererHost { |
123 public: | 83 public: |
124 ImmersiveFullscreenControllerDelegateMus(views::Widget* frame, | 84 ImmersiveFullscreenControllerDelegateMus(views::Widget* frame, |
125 ui::Window* frame_window) | 85 aura::Window* frame_window) |
126 : frame_(frame), frame_window_(frame_window) {} | 86 : frame_(frame), frame_window_(frame_window) {} |
127 ~ImmersiveFullscreenControllerDelegateMus() override { | 87 ~ImmersiveFullscreenControllerDelegateMus() override { |
128 DestroyTitleAreaWindow(); | 88 DestroyTitleAreaWindow(); |
129 } | 89 } |
130 | 90 |
131 // WmImmersiveFullscreenControllerDelegate: | 91 // WmImmersiveFullscreenControllerDelegate: |
132 void OnImmersiveRevealStarted() override { | 92 void OnImmersiveRevealStarted() override { |
133 CreateTitleAreaWindow(); | 93 CreateTitleAreaWindow(); |
134 SetVisibleFraction(0); | 94 SetVisibleFraction(0); |
135 } | 95 } |
136 void OnImmersiveRevealEnded() override { DestroyTitleAreaWindow(); } | 96 void OnImmersiveRevealEnded() override { DestroyTitleAreaWindow(); } |
137 void OnImmersiveFullscreenExited() override { DestroyTitleAreaWindow(); } | 97 void OnImmersiveFullscreenExited() override { DestroyTitleAreaWindow(); } |
138 void SetVisibleFraction(double visible_fraction) override { | 98 void SetVisibleFraction(double visible_fraction) override { |
139 if (!title_area_window_) | 99 aura::Window* title_area_window = GetTitleAreaWindow(); |
100 if (!title_area_window) | |
140 return; | 101 return; |
141 gfx::Rect bounds = title_area_window_->bounds(); | 102 gfx::Rect bounds = title_area_window->bounds(); |
142 bounds.set_y(frame_window_->bounds().y() - bounds.height() + | 103 bounds.set_y(frame_window_->bounds().y() - bounds.height() + |
143 visible_fraction * bounds.height()); | 104 visible_fraction * bounds.height()); |
144 title_area_window_->SetBounds(bounds); | 105 title_area_window->SetBounds(bounds); |
145 } | 106 } |
146 std::vector<gfx::Rect> GetVisibleBoundsInScreen() const override { | 107 std::vector<gfx::Rect> GetVisibleBoundsInScreen() const override { |
147 std::vector<gfx::Rect> result; | 108 std::vector<gfx::Rect> result; |
148 if (!title_area_window_) | 109 const aura::Window* title_area_window = GetTitleAreaWindow(); |
110 if (!title_area_window) | |
149 return result; | 111 return result; |
150 | 112 |
151 // Clip the bounds of the title area to that of the |frame_window_|. | 113 // Clip the bounds of the title area to that of the |frame_window_|. |
152 gfx::Rect visible_bounds = title_area_window_->bounds(); | 114 gfx::Rect visible_bounds = title_area_window->bounds(); |
153 visible_bounds.Intersect(frame_window_->bounds()); | 115 visible_bounds.Intersect(frame_window_->bounds()); |
154 // The intersection is in the coordinates of |title_area_window_|'s parent, | 116 // The intersection is in the coordinates of |title_area_window|'s parent, |
155 // convert to be in |title_area_window_| and then to screen. | 117 // convert to be in |title_area_window| and then to screen. |
156 visible_bounds -= title_area_window_->bounds().origin().OffsetFromOrigin(); | 118 visible_bounds -= title_area_window->bounds().origin().OffsetFromOrigin(); |
157 // TODO: this needs updating when parent of |title_area_window| is changed, | 119 // TODO: this needs updating when parent of |title_area_window| is changed, |
158 // DCHECK is to ensure when parent changes this code is updated. | 120 // DCHECK is to ensure when parent changes this code is updated. |
159 // http://crbug.com/640392. | 121 // http://crbug.com/640392. |
160 DCHECK_EQ(frame_window_->parent(), title_area_window_->parent()); | 122 DCHECK_EQ(frame_window_->parent(), title_area_window->parent()); |
161 result.push_back(WmWindowMus::Get(title_area_window_) | 123 result.push_back(WmWindowMus::Get(title_area_window) |
162 ->ConvertRectToScreen(visible_bounds)); | 124 ->ConvertRectToScreen(visible_bounds)); |
163 return result; | 125 return result; |
164 } | 126 } |
165 | 127 |
166 // DetachedTitleAreaRendererHost: | 128 // DetachedTitleAreaRendererHost: |
167 void OnDetachedTitleAreaRendererDestroyed( | 129 void OnDetachedTitleAreaRendererDestroyed( |
168 DetachedTitleAreaRenderer* renderer) override { | 130 DetachedTitleAreaRenderer* renderer) override { |
169 title_area_renderer_ = nullptr; | 131 title_area_renderer_ = nullptr; |
170 title_area_window_ = nullptr; | |
171 } | 132 } |
172 | 133 |
173 private: | 134 private: |
174 void CreateTitleAreaWindow() { | 135 void CreateTitleAreaWindow() { |
175 if (title_area_window_) | 136 if (GetTitleAreaWindow()) |
176 return; | 137 return; |
177 | 138 |
178 title_area_window_ = frame_window_->window_tree()->NewWindow(); | |
179 // TODO(sky): bounds aren't right here. Need to convert to display. | 139 // TODO(sky): bounds aren't right here. Need to convert to display. |
180 gfx::Rect bounds = frame_window_->bounds(); | 140 gfx::Rect bounds = frame_window_->bounds(); |
181 // Use the preferred size as when fullscreen the client area is generally | 141 // Use the preferred size as when fullscreen the client area is generally |
182 // set to 0. | 142 // set to 0. |
183 bounds.set_height( | 143 bounds.set_height( |
184 NonClientFrameController::GetPreferredClientAreaInsets().top()); | 144 NonClientFrameController::GetPreferredClientAreaInsets().top()); |
185 bounds.set_y(bounds.y() - bounds.height()); | 145 bounds.set_y(bounds.y() - bounds.height()); |
186 title_area_window_->SetBounds(bounds); | 146 title_area_renderer_ = new DetachedTitleAreaRenderer( |
187 // TODO: making the reveal window a sibling is likely problematic. | 147 this, frame_, bounds, DetachedTitleAreaRenderer::Source::MASH); |
188 // http://crbug.com/640392, see also comment in GetVisibleBoundsInScreen(). | |
189 frame_window_->parent()->AddChild(title_area_window_); | |
190 title_area_window_->Reorder(frame_window_, | |
191 ui::mojom::OrderDirection::ABOVE); | |
192 title_area_renderer_ = | |
193 new DetachedTitleAreaRenderer(this, frame_, title_area_window_, | |
194 DetachedTitleAreaRenderer::Source::MASH); | |
195 } | 148 } |
196 | 149 |
197 void DestroyTitleAreaWindow() { | 150 void DestroyTitleAreaWindow() { |
198 if (!title_area_window_) | 151 if (!GetTitleAreaWindow()) |
199 return; | 152 return; |
200 title_area_renderer_->Destroy(); | 153 title_area_renderer_->Destroy(); |
201 title_area_renderer_ = nullptr; | 154 title_area_renderer_ = nullptr; |
202 // TitleAreaRevealer ends up owning window. | 155 } |
203 title_area_window_ = nullptr; | 156 |
157 aura::Window* GetTitleAreaWindow() { | |
158 return const_cast<aura::Window*>( | |
159 const_cast<const ImmersiveFullscreenControllerDelegateMus*>(this) | |
160 ->GetTitleAreaWindow()); | |
161 } | |
162 const aura::Window* GetTitleAreaWindow() const { | |
163 return title_area_renderer_ | |
164 ? title_area_renderer_->widget()->GetNativeView() | |
165 : nullptr; | |
204 } | 166 } |
205 | 167 |
206 // The Widget immersive mode is operating on. | 168 // The Widget immersive mode is operating on. |
207 views::Widget* frame_; | 169 views::Widget* frame_; |
208 | 170 |
209 // The ui::Window associated with |frame_|. | 171 // The ui::Window associated with |frame_|. |
210 ui::Window* frame_window_; | 172 aura::Window* frame_window_; |
211 | |
212 // The window hosting the title area. | |
213 ui::Window* title_area_window_ = nullptr; | |
214 | 173 |
215 DetachedTitleAreaRenderer* title_area_renderer_ = nullptr; | 174 DetachedTitleAreaRenderer* title_area_renderer_ = nullptr; |
216 | 175 |
217 DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenControllerDelegateMus); | 176 DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenControllerDelegateMus); |
218 }; | 177 }; |
219 | 178 |
220 class WmNativeWidgetMus : public views::NativeWidgetMus { | 179 class WmNativeWidgetAura : public views::NativeWidgetAura { |
221 public: | 180 public: |
222 WmNativeWidgetMus(views::internal::NativeWidgetDelegate* delegate, | 181 WmNativeWidgetAura(views::internal::NativeWidgetDelegate* delegate, |
223 ui::Window* window, | 182 aura::WindowManagerClient* window_manager_client, |
224 ui::WindowManagerClient* window_manager_client) | 183 bool remove_standard_frame, |
225 : NativeWidgetMus(delegate, | 184 bool enable_immersive) |
226 window, | 185 : views::NativeWidgetAura(delegate, true), |
James Cook
2016/12/05 19:21:44
The "true" here for is_parallel_widget_in_window_m
sky
2016/12/05 21:39:19
Done.
| |
227 ui::mojom::CompositorFrameSinkType::UNDERLAY), | 186 remove_standard_frame_(remove_standard_frame), |
187 enable_immersive_(enable_immersive), | |
228 window_manager_client_(window_manager_client) {} | 188 window_manager_client_(window_manager_client) {} |
229 ~WmNativeWidgetMus() override {} | 189 ~WmNativeWidgetAura() override {} |
230 | 190 |
231 // NativeWidgetMus: | 191 // views::NativeWidgetAura: |
232 views::NonClientFrameView* CreateNonClientFrameView() override { | 192 views::NonClientFrameView* CreateNonClientFrameView() override { |
233 move_event_handler_.reset(new MoveEventHandler( | 193 move_event_handler_ = base::MakeUnique<MoveEventHandler>( |
234 window(), window_manager_client_, GetNativeView())); | 194 window_manager_client_, GetNativeView()); |
235 if (ShouldRemoveStandardFrame(window())) | 195 // TODO(sky): investigate why we have this. Seems this should be the same |
196 // as not specifying client area insets. | |
197 if (remove_standard_frame_) | |
236 return new EmptyDraggableNonClientFrameView(); | 198 return new EmptyDraggableNonClientFrameView(); |
237 if (GetWindowType(window()) == ui::mojom::WindowType::PANEL) | 199 aura::Window* window = GetNativeView(); |
200 if (window->GetProperty(aura::client::kWindowTypeKey) == | |
201 ui::mojom::WindowType::PANEL) | |
238 return new PanelFrameView(GetWidget(), PanelFrameView::FRAME_ASH); | 202 return new PanelFrameView(GetWidget(), PanelFrameView::FRAME_ASH); |
239 immersive_delegate_.reset( | 203 immersive_delegate_ = |
240 new ImmersiveFullscreenControllerDelegateMus(GetWidget(), window())); | 204 base::MakeUnique<ImmersiveFullscreenControllerDelegateMus>(GetWidget(), |
241 const bool enable_immersive = | 205 window); |
242 !window()->HasSharedProperty( | |
243 ui::mojom::WindowManager::kDisableImmersive_Property) || | |
244 !window()->GetSharedProperty<bool>( | |
245 ui::mojom::WindowManager::kDisableImmersive_Property); | |
246 return new CustomFrameViewMus(GetWidget(), immersive_delegate_.get(), | 206 return new CustomFrameViewMus(GetWidget(), immersive_delegate_.get(), |
247 enable_immersive); | 207 enable_immersive_); |
248 } | 208 } |
249 void InitNativeWidget(const views::Widget::InitParams& params) override { | 209 void InitNativeWidget(const views::Widget::InitParams& params) override { |
250 views::NativeWidgetMus::InitNativeWidget(params); | 210 views::NativeWidgetAura::InitNativeWidget(params); |
251 aura::WindowTreeHost* window_tree_host = GetNativeView()->GetHost(); | |
252 // TODO(sky): shadow should be determined by window type and shadow type. | 211 // TODO(sky): shadow should be determined by window type and shadow type. |
253 shadow_.reset(new Shadow); | 212 shadow_ = base::MakeUnique<Shadow>(); |
254 shadow_->Init(Shadow::STYLE_INACTIVE); | 213 shadow_->Init(Shadow::STYLE_INACTIVE); |
255 shadow_->Install(window()); | 214 aura::Window* window = GetNativeWindow(); |
256 ContentWindowLayoutManager* layout_manager = new ContentWindowLayoutManager( | 215 shadow_->Install(window); |
257 window_tree_host->window(), shadow_.get()); | 216 window->layer()->Add(shadow_->layer()); |
258 window_tree_host->window()->SetLayoutManager(layout_manager); | |
259 const int inset = Shadow::GetInteriorInsetForStyle(Shadow::STYLE_ACTIVE); | |
260 window_tree_host->SetOutputSurfacePaddingInPixels( | |
261 gfx::Insets(inset, inset, inset, inset)); | |
262 window_tree_host->window()->layer()->Add(shadow_->layer()); | |
263 shadow_->layer()->parent()->StackAtBottom(shadow_->layer()); | 217 shadow_->layer()->parent()->StackAtBottom(shadow_->layer()); |
264 } | 218 } |
219 void OnBoundsChanged(const gfx::Rect& old_bounds, | |
220 const gfx::Rect& new_bounds) override { | |
221 views::NativeWidgetAura::OnBoundsChanged(old_bounds, new_bounds); | |
222 if (shadow_) | |
223 shadow_->SetContentBounds(gfx::Rect(new_bounds.size())); | |
224 } | |
265 | 225 |
266 private: | 226 private: |
227 const bool remove_standard_frame_; | |
228 const bool enable_immersive_; | |
229 | |
267 // The shadow, may be null. | 230 // The shadow, may be null. |
268 std::unique_ptr<Shadow> shadow_; | 231 std::unique_ptr<Shadow> shadow_; |
269 | 232 |
270 std::unique_ptr<MoveEventHandler> move_event_handler_; | 233 std::unique_ptr<MoveEventHandler> move_event_handler_; |
271 | 234 |
272 ui::WindowManagerClient* window_manager_client_; | 235 aura::WindowManagerClient* window_manager_client_; |
273 | 236 |
274 std::unique_ptr<ImmersiveFullscreenControllerDelegateMus> immersive_delegate_; | 237 std::unique_ptr<ImmersiveFullscreenControllerDelegateMus> immersive_delegate_; |
275 | 238 |
276 DISALLOW_COPY_AND_ASSIGN(WmNativeWidgetMus); | 239 DISALLOW_COPY_AND_ASSIGN(WmNativeWidgetAura); |
277 }; | 240 }; |
278 | 241 |
279 class ClientViewMus : public views::ClientView { | 242 class ClientViewMus : public views::ClientView { |
280 public: | 243 public: |
281 ClientViewMus(views::Widget* widget, | 244 ClientViewMus(views::Widget* widget, |
282 views::View* contents_view, | 245 views::View* contents_view, |
283 NonClientFrameController* frame_controller) | 246 NonClientFrameController* frame_controller) |
284 : views::ClientView(widget, contents_view), | 247 : views::ClientView(widget, contents_view), |
285 frame_controller_(frame_controller) {} | 248 frame_controller_(frame_controller) {} |
286 ~ClientViewMus() override {} | 249 ~ClientViewMus() override {} |
287 | 250 |
288 // views::ClientView: | 251 // views::ClientView: |
289 bool CanClose() override { | 252 bool CanClose() override { |
290 if (!frame_controller_->window()) | 253 if (!frame_controller_->window()) |
291 return true; | 254 return true; |
292 | 255 |
293 frame_controller_->window()->RequestClose(); | 256 frame_controller_->window_manager_client()->RequestClose( |
257 frame_controller_->window()); | |
294 return false; | 258 return false; |
295 } | 259 } |
296 | 260 |
297 private: | 261 private: |
298 NonClientFrameController* frame_controller_; | 262 NonClientFrameController* frame_controller_; |
299 | 263 |
300 DISALLOW_COPY_AND_ASSIGN(ClientViewMus); | 264 DISALLOW_COPY_AND_ASSIGN(ClientViewMus); |
301 }; | 265 }; |
302 | 266 |
303 // Returns the frame insets to use when ShouldUseExtendedHitRegion() returns | 267 // Returns the frame insets to use when ShouldUseExtendedHitRegion() returns |
304 // true. | 268 // true. |
305 gfx::Insets GetExtendedHitRegion() { | 269 gfx::Insets GetExtendedHitRegion() { |
306 return gfx::Insets(kResizeOutsideBoundsSize, kResizeOutsideBoundsSize, | 270 return gfx::Insets(kResizeOutsideBoundsSize, kResizeOutsideBoundsSize, |
307 kResizeOutsideBoundsSize, kResizeOutsideBoundsSize); | 271 kResizeOutsideBoundsSize, kResizeOutsideBoundsSize); |
308 } | 272 } |
309 | 273 |
310 } // namespace | 274 } // namespace |
311 | 275 |
312 // static | 276 NonClientFrameController::NonClientFrameController( |
313 void NonClientFrameController::Create( | 277 aura::Window* parent, |
314 ui::Window* parent, | 278 aura::Window* context, |
315 ui::Window* window, | 279 const gfx::Rect& bounds, |
316 ui::WindowManagerClient* window_manager_client) { | 280 ui::mojom::WindowType window_type, |
317 new NonClientFrameController(parent, window, window_manager_client); | 281 std::map<std::string, std::vector<uint8_t>>* properties, |
282 WindowManager* window_manager) | |
283 : window_manager_client_(window_manager->window_manager_client()), | |
284 widget_(new views::Widget), | |
285 window_(nullptr) { | |
286 // To simplify things this code creates a Widget. While a Widget is created | |
287 // we need to ensure we don't inadvertently change random properties of the | |
288 // underlying ui::Window. For example, showing the Widget shouldn't change | |
289 // the bounds of the ui::Window in anyway. | |
290 // | |
291 // Assertions around these type matching exist in MusClient. | |
292 views::Widget::InitParams params( | |
293 static_cast<views::Widget::InitParams::Type>(window_type)); | |
294 params.parent = parent; | |
295 params.context = context; | |
James Cook
2016/12/05 19:21:44
nit: If either |parent| or |context| must be non-n
sky
2016/12/05 21:39:19
Done.
| |
296 // TODO: properly set |params.activatable|. Should key off whether underlying | |
297 // (mus) window can have focus. | |
298 params.delegate = this; | |
299 params.bounds = bounds; | |
300 WmNativeWidgetAura* native_widget = new WmNativeWidgetAura( | |
301 widget_, window_manager_client_, ShouldRemoveStandardFrame(*properties), | |
302 ShouldEnableImmersive(*properties)); | |
303 window_ = native_widget->GetNativeView(); | |
304 WmWindowMus* wm_window = WmWindowMus::Get(window_); | |
305 wm_window->set_widget(widget_, WmWindowMus::WidgetCreationType::FOR_CLIENT); | |
306 window_->AddObserver(this); | |
307 params.native_widget = native_widget; | |
308 aura::SetWindowType(window_, window_type); | |
309 aura::PropertyConverter* property_converter = | |
310 window_manager->property_converter(); | |
311 for (auto& property_pair : *properties) { | |
312 property_converter->SetPropertyFromTransportValue( | |
313 window_, property_pair.first, &property_pair.second); | |
314 } | |
315 // Applying properties will have set the show state if specified. | |
316 // NativeWidgetAura resets the show state from |params|, so we need to update | |
317 // |params|. | |
318 params.show_state = window_->GetProperty(aura::client::kShowStateKey); | |
319 widget_->Init(params); | |
320 did_init_native_widget_ = true; | |
321 | |
322 widget_->ShowInactive(); | |
323 | |
324 const int shadow_inset = | |
325 Shadow::GetInteriorInsetForStyle(Shadow::STYLE_ACTIVE); | |
326 const gfx::Insets extended_hit_region = | |
327 wm_window->ShouldUseExtendedHitRegion() ? GetExtendedHitRegion() | |
328 : gfx::Insets(); | |
329 window_manager_client_->SetUnderlaySurfaceOffsetAndExtendedHitArea( | |
330 window_, gfx::Vector2d(shadow_inset, shadow_inset), extended_hit_region); | |
318 } | 331 } |
319 | 332 |
320 // static | 333 // static |
334 NonClientFrameController* NonClientFrameController::Get(aura::Window* window) { | |
335 return window->GetProperty(kNonClientFrameControllerKey); | |
336 } | |
337 | |
338 // static | |
321 gfx::Insets NonClientFrameController::GetPreferredClientAreaInsets() { | 339 gfx::Insets NonClientFrameController::GetPreferredClientAreaInsets() { |
322 // TODO(sky): figure out a better way to get this rather than hard coding. | 340 // TODO(sky): figure out a better way to get this rather than hard coding. |
323 // This value comes from the header (see DefaultHeaderPainter::LayoutHeader, | 341 // This value comes from the header (see DefaultHeaderPainter::LayoutHeader, |
324 // which uses the preferred height of the CaptionButtonContainer, which uses | 342 // which uses the preferred height of the CaptionButtonContainer, which uses |
325 // the height of the close button). | 343 // the height of the close button). |
326 return gfx::Insets( | 344 return gfx::Insets( |
327 GetAshLayoutSize(AshLayoutSize::NON_BROWSER_CAPTION_BUTTON).height(), 0, | 345 GetAshLayoutSize(AshLayoutSize::NON_BROWSER_CAPTION_BUTTON).height(), 0, |
328 0, 0); | 346 0, 0); |
329 } | 347 } |
330 | 348 |
331 // static | 349 // static |
332 int NonClientFrameController::GetMaxTitleBarButtonWidth() { | 350 int NonClientFrameController::GetMaxTitleBarButtonWidth() { |
333 // TODO(sky): same comment as for GetPreferredClientAreaInsets(). | 351 // TODO(sky): same comment as for GetPreferredClientAreaInsets(). |
334 return GetAshLayoutSize(AshLayoutSize::NON_BROWSER_CAPTION_BUTTON).width() * | 352 return GetAshLayoutSize(AshLayoutSize::NON_BROWSER_CAPTION_BUTTON).width() * |
335 3; | 353 3; |
336 } | 354 } |
337 | 355 |
338 NonClientFrameController::NonClientFrameController( | 356 void NonClientFrameController::SetClientArea( |
339 ui::Window* parent, | 357 const gfx::Insets& insets, |
340 ui::Window* window, | 358 const std::vector<gfx::Rect>& additional_client_areas) { |
341 ui::WindowManagerClient* window_manager_client) | 359 client_area_insets_ = insets; |
342 : widget_(new views::Widget), window_(window) { | 360 additional_client_areas_ = additional_client_areas; |
343 WmWindowMus* wm_window = WmWindowMus::Get(window); | |
344 wm_window->set_widget(widget_, WmWindowMus::WidgetCreationType::FOR_CLIENT); | |
345 window_->AddObserver(this); | |
346 | |
347 // To simplify things this code creates a Widget. While a Widget is created | |
348 // we need to ensure we don't inadvertently change random properties of the | |
349 // underlying ui::Window. For example, showing the Widget shouldn't change | |
350 // the bounds of the ui::Window in anyway. | |
351 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
352 // We initiate focus at the mus level, not at the views level. | |
353 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; | |
354 params.delegate = this; | |
355 params.native_widget = | |
356 new WmNativeWidgetMus(widget_, window, window_manager_client); | |
357 widget_->Init(params); | |
358 | |
359 parent->AddChild(window); | |
360 | |
361 widget_->ShowInactive(); | |
362 | |
363 const int shadow_inset = | |
364 Shadow::GetInteriorInsetForStyle(Shadow::STYLE_ACTIVE); | |
365 const gfx::Insets extended_hit_region = | |
366 wm_window->ShouldUseExtendedHitRegion() ? GetExtendedHitRegion() | |
367 : gfx::Insets(); | |
368 window_manager_client->SetUnderlaySurfaceOffsetAndExtendedHitArea( | |
369 window, gfx::Vector2d(shadow_inset, shadow_inset), extended_hit_region); | |
370 } | 361 } |
371 | 362 |
372 NonClientFrameController::~NonClientFrameController() { | 363 NonClientFrameController::~NonClientFrameController() { |
373 if (window_) | 364 if (window_) |
374 window_->RemoveObserver(this); | 365 window_->RemoveObserver(this); |
375 if (detached_title_area_renderer_) | 366 if (detached_title_area_renderer_) |
376 detached_title_area_renderer_->Destroy(); | 367 detached_title_area_renderer_->Destroy(); |
377 } | 368 } |
378 | 369 |
379 void NonClientFrameController::OnDetachedTitleAreaRendererDestroyed( | 370 void NonClientFrameController::OnDetachedTitleAreaRendererDestroyed( |
380 DetachedTitleAreaRenderer* renderer) { | 371 DetachedTitleAreaRenderer* renderer) { |
381 DCHECK_EQ(detached_title_area_renderer_, renderer); | 372 DCHECK_EQ(detached_title_area_renderer_, renderer); |
382 detached_title_area_renderer_ = nullptr; | 373 detached_title_area_renderer_ = nullptr; |
383 } | 374 } |
384 | 375 |
385 base::string16 NonClientFrameController::GetWindowTitle() const { | 376 base::string16 NonClientFrameController::GetWindowTitle() const { |
386 if (!window_->HasSharedProperty( | 377 if (!window_ || !window_->GetProperty(aura::client::kTitleKey)) |
387 ui::mojom::WindowManager::kWindowTitle_Property)) { | |
388 return base::string16(); | 378 return base::string16(); |
389 } | |
390 | 379 |
391 base::string16 title = window_->GetSharedProperty<base::string16>( | 380 base::string16 title = *window_->GetProperty(aura::client::kTitleKey); |
392 ui::mojom::WindowManager::kWindowTitle_Property); | |
393 | 381 |
394 if (IsWindowJanky(window_)) | 382 if (window_->GetProperty(kWindowIsJanky)) |
395 title += base::ASCIIToUTF16(" !! Not responding !!"); | 383 title += base::ASCIIToUTF16(" !! Not responding !!"); |
396 | 384 |
397 return title; | 385 return title; |
398 } | 386 } |
399 | 387 |
400 bool NonClientFrameController::CanResize() const { | 388 bool NonClientFrameController::CanResize() const { |
401 return window_ && (::ash::mus::GetResizeBehavior(window_) & | 389 return window_ && WmWindowMus::Get(window_)->CanResize(); |
402 ui::mojom::kResizeBehaviorCanResize); | |
403 } | 390 } |
404 | 391 |
405 bool NonClientFrameController::CanMaximize() const { | 392 bool NonClientFrameController::CanMaximize() const { |
406 return window_ && (::ash::mus::GetResizeBehavior(window_) & | 393 return window_ && WmWindowMus::Get(window_)->CanMaximize(); |
407 ui::mojom::kResizeBehaviorCanMaximize); | |
408 } | 394 } |
409 | 395 |
410 bool NonClientFrameController::CanMinimize() const { | 396 bool NonClientFrameController::CanMinimize() const { |
411 return window_ && (::ash::mus::GetResizeBehavior(window_) & | 397 return window_ && WmWindowMus::Get(window_)->CanMinimize(); |
412 ui::mojom::kResizeBehaviorCanMinimize); | |
413 } | 398 } |
414 | 399 |
415 bool NonClientFrameController::ShouldShowWindowTitle() const { | 400 bool NonClientFrameController::ShouldShowWindowTitle() const { |
416 // Only draw the title if the client hasn't declared any additional client | 401 // Only draw the title if the client hasn't declared any additional client |
417 // areas which might conflict with it. | 402 // areas which might conflict with it. |
418 return window_ && window_->additional_client_areas().empty(); | 403 return window_ && additional_client_areas_.empty(); |
419 } | 404 } |
420 | 405 |
421 views::ClientView* NonClientFrameController::CreateClientView( | 406 views::ClientView* NonClientFrameController::CreateClientView( |
422 views::Widget* widget) { | 407 views::Widget* widget) { |
423 return new ClientViewMus(widget, GetContentsView(), this); | 408 return new ClientViewMus(widget, GetContentsView(), this); |
424 } | 409 } |
425 | 410 |
426 void NonClientFrameController::OnTreeChanged(const TreeChangeParams& params) { | 411 void NonClientFrameController::OnWindowHierarchyChanged( |
412 const HierarchyChangeParams& params) { | |
427 if (params.new_parent != window_ || | 413 if (params.new_parent != window_ || |
428 !ShouldRenderParentTitleArea(params.target)) { | 414 !params.target->GetProperty(kRenderTitleAreaProperty)) { |
429 return; | 415 return; |
430 } | 416 } |
431 if (detached_title_area_renderer_) { | 417 if (detached_title_area_renderer_) { |
432 detached_title_area_renderer_->Destroy(); | 418 detached_title_area_renderer_->Destroy(); |
433 detached_title_area_renderer_ = nullptr; | 419 detached_title_area_renderer_ = nullptr; |
434 } | 420 } |
435 detached_title_area_renderer_ = new DetachedTitleAreaRenderer( | 421 detached_title_area_renderer_ = |
436 this, widget_, params.target, DetachedTitleAreaRenderer::Source::CLIENT); | 422 new DetachedTitleAreaRenderer(this, widget_, params.target->bounds(), |
423 DetachedTitleAreaRenderer::Source::CLIENT); | |
437 } | 424 } |
438 | 425 |
439 void NonClientFrameController::OnWindowSharedPropertyChanged( | 426 void NonClientFrameController::OnWindowPropertyChanged(aura::Window* window, |
440 ui::Window* window, | 427 const void* key, |
441 const std::string& name, | 428 intptr_t old) { |
442 const std::vector<uint8_t>* old_data, | 429 // Properties are applied before the call to InitNativeWidget(). Ignore |
443 const std::vector<uint8_t>* new_data) { | 430 // processing changes in this case as the Widget is not in a state where we |
444 if (name == ui::mojom::WindowManager::kResizeBehavior_Property) | 431 // can use it yet. |
445 widget_->OnSizeConstraintsChanged(); | 432 if (!did_init_native_widget_) |
446 else if (name == ui::mojom::WindowManager::kWindowTitle_Property) | 433 return; |
447 widget_->UpdateWindowTitle(); | |
448 } | |
449 | 434 |
450 void NonClientFrameController::OnWindowLocalPropertyChanged(ui::Window* window, | 435 if (key == kWindowIsJanky) { |
451 const void* key, | |
452 intptr_t old) { | |
453 if (IsWindowJankyProperty(key)) { | |
454 widget_->UpdateWindowTitle(); | 436 widget_->UpdateWindowTitle(); |
455 widget_->non_client_view()->frame_view()->SchedulePaint(); | 437 widget_->non_client_view()->frame_view()->SchedulePaint(); |
438 } else if (key == aura::client::kResizeBehaviorKey) { | |
439 widget_->OnSizeConstraintsChanged(); | |
440 } else if (key == aura::client::kTitleKey) { | |
441 widget_->UpdateWindowTitle(); | |
456 } | 442 } |
457 } | 443 } |
458 | 444 |
459 void NonClientFrameController::OnWindowDestroyed(ui::Window* window) { | 445 void NonClientFrameController::OnWindowDestroyed(aura::Window* window) { |
460 window_->RemoveObserver(this); | 446 window_->RemoveObserver(this); |
461 window_ = nullptr; | 447 window_ = nullptr; |
462 } | 448 } |
463 | 449 |
464 } // namespace mus | 450 } // namespace mus |
465 } // namespace ash | 451 } // namespace ash |
OLD | NEW |