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

Side by Side Diff: ash/mus/non_client_frame_controller.cc

Issue 2277563002: Wires up immersive mode for chrome and mash (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix crash Created 4 years, 4 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 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/mus/bridge/wm_window_mus.h" 16 #include "ash/mus/bridge/wm_window_mus.h"
17 #include "ash/mus/frame/custom_frame_view_mus.h"
18 #include "ash/mus/frame/detached_title_area_renderer.h"
17 #include "ash/mus/move_event_handler.h" 19 #include "ash/mus/move_event_handler.h"
18 #include "ash/mus/property_util.h" 20 #include "ash/mus/property_util.h"
19 #include "ash/mus/shadow.h" 21 #include "ash/mus/shadow.h"
22 #include "ash/shared/immersive_fullscreen_controller_delegate.h"
20 #include "base/macros.h" 23 #include "base/macros.h"
21 #include "base/strings/utf_string_conversions.h" 24 #include "base/strings/utf_string_conversions.h"
22 #include "services/ui/public/cpp/property_type_converters.h" 25 #include "services/ui/public/cpp/property_type_converters.h"
23 #include "services/ui/public/cpp/window.h" 26 #include "services/ui/public/cpp/window.h"
24 #include "services/ui/public/cpp/window_manager_delegate.h" 27 #include "services/ui/public/cpp/window_manager_delegate.h"
25 #include "services/ui/public/cpp/window_property.h" 28 #include "services/ui/public/cpp/window_property.h"
29 #include "services/ui/public/cpp/window_tree_client.h"
26 #include "services/ui/public/interfaces/window_manager.mojom.h" 30 #include "services/ui/public/interfaces/window_manager.mojom.h"
27 #include "services/ui/public/interfaces/window_tree_host.mojom.h" 31 #include "services/ui/public/interfaces/window_tree_host.mojom.h"
28 #include "ui/aura/layout_manager.h" 32 #include "ui/aura/layout_manager.h"
29 #include "ui/aura/window.h" 33 #include "ui/aura/window.h"
30 #include "ui/aura/window_tree_host.h" 34 #include "ui/aura/window_tree_host.h"
31 #include "ui/base/hit_test.h" 35 #include "ui/base/hit_test.h"
32 #include "ui/compositor/layer.h" 36 #include "ui/compositor/layer.h"
33 #include "ui/gfx/geometry/vector2d.h" 37 #include "ui/gfx/geometry/vector2d.h"
34 #include "ui/views/mus/native_widget_mus.h" 38 #include "ui/views/mus/native_widget_mus.h"
35 #include "ui/views/widget/widget.h" 39 #include "ui/views/widget/widget.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {} 107 void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {}
104 void ResetWindowControls() override {} 108 void ResetWindowControls() override {}
105 void UpdateWindowIcon() override {} 109 void UpdateWindowIcon() override {}
106 void UpdateWindowTitle() override {} 110 void UpdateWindowTitle() override {}
107 void SizeConstraintsChanged() override {} 111 void SizeConstraintsChanged() override {}
108 112
109 private: 113 private:
110 DISALLOW_COPY_AND_ASSIGN(EmptyDraggableNonClientFrameView); 114 DISALLOW_COPY_AND_ASSIGN(EmptyDraggableNonClientFrameView);
111 }; 115 };
112 116
117 // Creates a ui::Window to host the top container when in immersive mode. The
118 // top container contains a DetachedTitleAreaRenderer, which handles drawing and
119 // events.
120 class ImmersiveFullscreenControllerDelegateMus
121 : public ImmersiveFullscreenControllerDelegate,
122 public DetachedTitleAreaRendererHost {
123 public:
124 ImmersiveFullscreenControllerDelegateMus(views::Widget* frame,
125 ui::Window* frame_window)
126 : frame_(frame), frame_window_(frame_window) {}
127 ~ImmersiveFullscreenControllerDelegateMus() override {
128 DestroyTitleAreaWindow();
129 }
130
131 // WmImmersiveFullscreenControllerDelegate:
132 void OnImmersiveRevealStarted() override { SetVisibleFraction(0); }
James Cook 2016/08/24 17:00:32 I found this a little confusing. I expected it to
sky 2016/08/24 19:23:29 Done.
133 void OnImmersiveRevealEnded() override { SetVisibleFraction(0); }
134 void OnImmersiveFullscreenExited() override { SetVisibleFraction(0); }
135 void SetVisibleFraction(double visible_fraction) override {
136 if (visible_fraction == 0) {
137 DestroyTitleAreaWindow();
138 return;
139 }
140 CreateTitleAreaWindow();
141 if (!title_area_window_)
142 return;
143 gfx::Rect bounds = title_area_window_->bounds();
144 bounds.set_y(frame_window_->bounds().y() - bounds.height() +
145 visible_fraction * bounds.height());
146 title_area_window_->SetBounds(bounds);
147 }
148 std::vector<gfx::Rect> GetVisibleBoundsInScreen() const override {
149 std::vector<gfx::Rect> result;
150 if (!title_area_window_)
151 return result;
152
153 // Clip the bounds of the title area to that of the |frame_window_|.
154 gfx::Rect visible_bounds = title_area_window_->bounds();
155 visible_bounds.Intersect(frame_window_->bounds());
156 visible_bounds -= title_area_window_->bounds().origin().OffsetFromOrigin();
James Cook 2016/08/24 17:00:32 Do you need this translation? I'm having a hard ti
sky 2016/08/24 19:23:29 visible_bounds is in the coordinates of the parent
157 result.push_back(WmWindowMus::Get(title_area_window_)
158 ->ConvertRectToScreen(visible_bounds));
159 return result;
160 }
161
162 // DetachedTitleAreaRendererHost:
163 void OnDetachedTitleAreaRendererDestroyed(
164 DetachedTitleAreaRenderer* renderer) override {
165 title_area_renderer_ = nullptr;
166 title_area_window_ = nullptr;
167 }
168
169 private:
170 void CreateTitleAreaWindow() {
171 if (title_area_window_)
172 return;
173
174 title_area_window_ = frame_window_->window_tree()->NewWindow();
175 // TODO(sky): bounds aren't right here. Need to convert to display.
176 gfx::Rect bounds = frame_window_->bounds();
177 // Use the preferred size as when fullscreen the client area is generally
178 // set to 0.
179 bounds.set_height(
180 NonClientFrameController::GetPreferredClientAreaInsets().top());
181 bounds.set_y(bounds.y() - bounds.height());
182 title_area_window_->SetBounds(bounds);
183 // TODO: making the reveal window a sibling is likely problematic.
184 // http://crbug.com/640392,
185 frame_window_->parent()->AddChild(title_area_window_);
186 title_area_window_->Reorder(frame_window_,
187 ui::mojom::OrderDirection::ABOVE);
188 title_area_renderer_ =
189 new DetachedTitleAreaRenderer(this, frame_, title_area_window_,
190 DetachedTitleAreaRenderer::Source::MASH);
191 }
192
193 void DestroyTitleAreaWindow() {
194 if (!title_area_window_)
195 return;
196 title_area_renderer_->Destroy();
197 title_area_renderer_ = nullptr;
198 // TitleAreaRevealer ends up owning window.
199 title_area_window_ = nullptr;
200 }
201
202 // The Widget immersive mode is operating on.
203 views::Widget* frame_;
204
205 // The ui::Window associated with |frame_|.
206 ui::Window* frame_window_;
207
208 // The window hosting the title area.
209 ui::Window* title_area_window_ = nullptr;
210
211 DetachedTitleAreaRenderer* title_area_renderer_ = nullptr;
212
213 DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenControllerDelegateMus);
214 };
215
113 class WmNativeWidgetMus : public views::NativeWidgetMus { 216 class WmNativeWidgetMus : public views::NativeWidgetMus {
114 public: 217 public:
115 WmNativeWidgetMus(views::internal::NativeWidgetDelegate* delegate, 218 WmNativeWidgetMus(views::internal::NativeWidgetDelegate* delegate,
116 ui::Window* window, 219 ui::Window* window,
117 ui::WindowManagerClient* window_manager_client) 220 ui::WindowManagerClient* window_manager_client)
118 : NativeWidgetMus(delegate, window, ui::mojom::SurfaceType::UNDERLAY), 221 : NativeWidgetMus(delegate, window, ui::mojom::SurfaceType::UNDERLAY),
119 window_manager_client_(window_manager_client) {} 222 window_manager_client_(window_manager_client) {}
120 ~WmNativeWidgetMus() override {} 223 ~WmNativeWidgetMus() override {}
121 224
122 // NativeWidgetMus: 225 // NativeWidgetMus:
123 views::NonClientFrameView* CreateNonClientFrameView() override { 226 views::NonClientFrameView* CreateNonClientFrameView() override {
124 move_event_handler_.reset(new MoveEventHandler( 227 move_event_handler_.reset(new MoveEventHandler(
125 window(), window_manager_client_, GetNativeView())); 228 window(), window_manager_client_, GetNativeView()));
126 if (ShouldRemoveStandardFrame(window())) 229 if (ShouldRemoveStandardFrame(window()))
127 return new EmptyDraggableNonClientFrameView(); 230 return new EmptyDraggableNonClientFrameView();
128 return new CustomFrameViewAsh(GetWidget()); 231 immersive_delegate_.reset(
232 new ImmersiveFullscreenControllerDelegateMus(GetWidget(), window()));
233 const bool enable_immersive =
234 !window()->HasSharedProperty(
235 ui::mojom::WindowManager::kDisableImmersive_Property) ||
236 !window()->GetSharedProperty<bool>(
237 ui::mojom::WindowManager::kDisableImmersive_Property);
238 return new CustomFrameViewMus(GetWidget(), immersive_delegate_.get(),
239 enable_immersive);
129 } 240 }
130 void InitNativeWidget(const views::Widget::InitParams& params) override { 241 void InitNativeWidget(const views::Widget::InitParams& params) override {
131 views::NativeWidgetMus::InitNativeWidget(params); 242 views::NativeWidgetMus::InitNativeWidget(params);
132 aura::WindowTreeHost* window_tree_host = GetNativeView()->GetHost(); 243 aura::WindowTreeHost* window_tree_host = GetNativeView()->GetHost();
133 // TODO(sky): shadow should be determined by window type and shadow type. 244 // TODO(sky): shadow should be determined by window type and shadow type.
134 shadow_.reset(new Shadow); 245 shadow_.reset(new Shadow);
135 shadow_->Init(Shadow::STYLE_INACTIVE); 246 shadow_->Init(Shadow::STYLE_INACTIVE);
136 shadow_->Install(window()); 247 shadow_->Install(window());
137 ContentWindowLayoutManager* layout_manager = new ContentWindowLayoutManager( 248 ContentWindowLayoutManager* layout_manager = new ContentWindowLayoutManager(
138 window_tree_host->window(), shadow_.get()); 249 window_tree_host->window(), shadow_.get());
139 window_tree_host->window()->SetLayoutManager(layout_manager); 250 window_tree_host->window()->SetLayoutManager(layout_manager);
140 const int inset = Shadow::GetInteriorInsetForStyle(Shadow::STYLE_ACTIVE); 251 const int inset = Shadow::GetInteriorInsetForStyle(Shadow::STYLE_ACTIVE);
141 window_tree_host->SetOutputSurfacePadding( 252 window_tree_host->SetOutputSurfacePadding(
142 gfx::Insets(inset, inset, inset, inset)); 253 gfx::Insets(inset, inset, inset, inset));
143 window_tree_host->window()->layer()->Add(shadow_->layer()); 254 window_tree_host->window()->layer()->Add(shadow_->layer());
144 shadow_->layer()->parent()->StackAtBottom(shadow_->layer()); 255 shadow_->layer()->parent()->StackAtBottom(shadow_->layer());
145 } 256 }
146 257
147 private: 258 private:
148 // The shadow, may be null. 259 // The shadow, may be null.
149 std::unique_ptr<Shadow> shadow_; 260 std::unique_ptr<Shadow> shadow_;
150 261
151 std::unique_ptr<MoveEventHandler> move_event_handler_; 262 std::unique_ptr<MoveEventHandler> move_event_handler_;
152 263
153 ui::WindowManagerClient* window_manager_client_; 264 ui::WindowManagerClient* window_manager_client_;
154 265
266 std::unique_ptr<ImmersiveFullscreenControllerDelegateMus> immersive_delegate_;
267
155 DISALLOW_COPY_AND_ASSIGN(WmNativeWidgetMus); 268 DISALLOW_COPY_AND_ASSIGN(WmNativeWidgetMus);
156 }; 269 };
157 270
158 class ClientViewMus : public views::ClientView { 271 class ClientViewMus : public views::ClientView {
159 public: 272 public:
160 ClientViewMus(views::Widget* widget, 273 ClientViewMus(views::Widget* widget,
161 views::View* contents_view, 274 views::View* contents_view,
162 NonClientFrameController* frame_controller) 275 NonClientFrameController* frame_controller)
163 : views::ClientView(widget, contents_view), 276 : views::ClientView(widget, contents_view),
164 frame_controller_(frame_controller) {} 277 frame_controller_(frame_controller) {}
(...skipping 18 matching lines...) Expand all
183 // true. 296 // true.
184 gfx::Insets GetExtendedHitRegion() { 297 gfx::Insets GetExtendedHitRegion() {
185 return gfx::Insets(kResizeOutsideBoundsSize, kResizeOutsideBoundsSize, 298 return gfx::Insets(kResizeOutsideBoundsSize, kResizeOutsideBoundsSize,
186 kResizeOutsideBoundsSize, kResizeOutsideBoundsSize); 299 kResizeOutsideBoundsSize, kResizeOutsideBoundsSize);
187 } 300 }
188 301
189 } // namespace 302 } // namespace
190 303
191 // static 304 // static
192 void NonClientFrameController::Create( 305 void NonClientFrameController::Create(
193 shell::Connector* connector,
194 ui::Window* parent, 306 ui::Window* parent,
195 ui::Window* window, 307 ui::Window* window,
196 ui::WindowManagerClient* window_manager_client) { 308 ui::WindowManagerClient* window_manager_client) {
197 new NonClientFrameController(connector, parent, window, 309 new NonClientFrameController(parent, window, window_manager_client);
198 window_manager_client);
199 } 310 }
200 311
201 // static 312 // static
202 gfx::Insets NonClientFrameController::GetPreferredClientAreaInsets() { 313 gfx::Insets NonClientFrameController::GetPreferredClientAreaInsets() {
203 // TODO(sky): figure out a better way to get this rather than hard coding. 314 // TODO(sky): figure out a better way to get this rather than hard coding.
204 // This value comes from the header (see DefaultHeaderPainter::LayoutHeader, 315 // This value comes from the header (see DefaultHeaderPainter::LayoutHeader,
205 // which uses the preferred height of the CaptionButtonContainer, which uses 316 // which uses the preferred height of the CaptionButtonContainer, which uses
206 // the height of the close button). 317 // the height of the close button).
207 return gfx::Insets( 318 return gfx::Insets(
208 GetAshLayoutSize(AshLayoutSize::NON_BROWSER_CAPTION_BUTTON).height(), 0, 319 GetAshLayoutSize(AshLayoutSize::NON_BROWSER_CAPTION_BUTTON).height(), 0,
209 0, 0); 320 0, 0);
210 } 321 }
211 322
212 // static 323 // static
213 int NonClientFrameController::GetMaxTitleBarButtonWidth() { 324 int NonClientFrameController::GetMaxTitleBarButtonWidth() {
214 // TODO(sky): same comment as for GetPreferredClientAreaInsets(). 325 // TODO(sky): same comment as for GetPreferredClientAreaInsets().
215 return GetAshLayoutSize(AshLayoutSize::NON_BROWSER_CAPTION_BUTTON).width() * 326 return GetAshLayoutSize(AshLayoutSize::NON_BROWSER_CAPTION_BUTTON).width() *
216 3; 327 3;
217 } 328 }
218 329
219 NonClientFrameController::NonClientFrameController( 330 NonClientFrameController::NonClientFrameController(
220 shell::Connector* connector,
221 ui::Window* parent, 331 ui::Window* parent,
222 ui::Window* window, 332 ui::Window* window,
223 ui::WindowManagerClient* window_manager_client) 333 ui::WindowManagerClient* window_manager_client)
224 : widget_(new views::Widget), window_(window) { 334 : widget_(new views::Widget), window_(window) {
225 WmWindowMus* wm_window = WmWindowMus::Get(window); 335 WmWindowMus* wm_window = WmWindowMus::Get(window);
226 wm_window->set_widget(widget_, WmWindowMus::WidgetCreationType::FOR_CLIENT); 336 wm_window->set_widget(widget_, WmWindowMus::WidgetCreationType::FOR_CLIENT);
227 window_->AddObserver(this); 337 window_->AddObserver(this);
228 338
229 // To simplify things this code creates a Widget. While a Widget is created 339 // To simplify things this code creates a Widget. While a Widget is created
230 // we need to ensure we don't inadvertently change random properties of the 340 // we need to ensure we don't inadvertently change random properties of the
(...skipping 16 matching lines...) Expand all
247 const gfx::Insets extended_hit_region = 357 const gfx::Insets extended_hit_region =
248 wm_window->ShouldUseExtendedHitRegion() ? GetExtendedHitRegion() 358 wm_window->ShouldUseExtendedHitRegion() ? GetExtendedHitRegion()
249 : gfx::Insets(); 359 : gfx::Insets();
250 window_manager_client->SetUnderlaySurfaceOffsetAndExtendedHitArea( 360 window_manager_client->SetUnderlaySurfaceOffsetAndExtendedHitArea(
251 window, gfx::Vector2d(shadow_inset, shadow_inset), extended_hit_region); 361 window, gfx::Vector2d(shadow_inset, shadow_inset), extended_hit_region);
252 } 362 }
253 363
254 NonClientFrameController::~NonClientFrameController() { 364 NonClientFrameController::~NonClientFrameController() {
255 if (window_) 365 if (window_)
256 window_->RemoveObserver(this); 366 window_->RemoveObserver(this);
367 if (detached_title_area_renderer_)
368 detached_title_area_renderer_->Destroy();
369 }
370
371 void NonClientFrameController::OnDetachedTitleAreaRendererDestroyed(
372 DetachedTitleAreaRenderer* renderer) {
373 DCHECK_EQ(detached_title_area_renderer_, renderer);
374 detached_title_area_renderer_ = nullptr;
257 } 375 }
258 376
259 base::string16 NonClientFrameController::GetWindowTitle() const { 377 base::string16 NonClientFrameController::GetWindowTitle() const {
260 if (!window_->HasSharedProperty( 378 if (!window_->HasSharedProperty(
261 ui::mojom::WindowManager::kWindowTitle_Property)) { 379 ui::mojom::WindowManager::kWindowTitle_Property)) {
262 return base::string16(); 380 return base::string16();
263 } 381 }
264 382
265 base::string16 title = window_->GetSharedProperty<base::string16>( 383 base::string16 title = window_->GetSharedProperty<base::string16>(
266 ui::mojom::WindowManager::kWindowTitle_Property); 384 ui::mojom::WindowManager::kWindowTitle_Property);
(...skipping 30 matching lines...) Expand all
297 // Only draw the title if the client hasn't declared any additional client 415 // Only draw the title if the client hasn't declared any additional client
298 // areas which might conflict with it. 416 // areas which might conflict with it.
299 return window_ && window_->additional_client_areas().empty(); 417 return window_ && window_->additional_client_areas().empty();
300 } 418 }
301 419
302 views::ClientView* NonClientFrameController::CreateClientView( 420 views::ClientView* NonClientFrameController::CreateClientView(
303 views::Widget* widget) { 421 views::Widget* widget) {
304 return new ClientViewMus(widget, GetContentsView(), this); 422 return new ClientViewMus(widget, GetContentsView(), this);
305 } 423 }
306 424
425 void NonClientFrameController::OnTreeChanged(const TreeChangeParams& params) {
426 if (params.new_parent == window_ &&
427 ShouldRenderParentTitleArea(params.target)) {
James Cook 2016/08/24 17:00:32 optional nit: early return?
sky 2016/08/24 19:23:29 Done.
428 if (detached_title_area_renderer_) {
429 detached_title_area_renderer_->Destroy();
430 detached_title_area_renderer_ = nullptr;
431 }
432 detached_title_area_renderer_ = new DetachedTitleAreaRenderer(
433 this, widget_, params.target,
434 DetachedTitleAreaRenderer::Source::CLIENT);
435 }
436 }
437
307 void NonClientFrameController::OnWindowSharedPropertyChanged( 438 void NonClientFrameController::OnWindowSharedPropertyChanged(
308 ui::Window* window, 439 ui::Window* window,
309 const std::string& name, 440 const std::string& name,
310 const std::vector<uint8_t>* old_data, 441 const std::vector<uint8_t>* old_data,
311 const std::vector<uint8_t>* new_data) { 442 const std::vector<uint8_t>* new_data) {
312 if (name == ui::mojom::WindowManager::kResizeBehavior_Property) 443 if (name == ui::mojom::WindowManager::kResizeBehavior_Property)
313 widget_->OnSizeConstraintsChanged(); 444 widget_->OnSizeConstraintsChanged();
314 else if (name == ui::mojom::WindowManager::kWindowTitle_Property) 445 else if (name == ui::mojom::WindowManager::kWindowTitle_Property)
315 widget_->UpdateWindowTitle(); 446 widget_->UpdateWindowTitle();
316 } 447 }
317 448
318 void NonClientFrameController::OnWindowLocalPropertyChanged(ui::Window* window, 449 void NonClientFrameController::OnWindowLocalPropertyChanged(ui::Window* window,
319 const void* key, 450 const void* key,
320 intptr_t old) { 451 intptr_t old) {
321 if (IsWindowJankyProperty(key)) { 452 if (IsWindowJankyProperty(key)) {
322 widget_->UpdateWindowTitle(); 453 widget_->UpdateWindowTitle();
323 widget_->non_client_view()->frame_view()->SchedulePaint(); 454 widget_->non_client_view()->frame_view()->SchedulePaint();
324 } 455 }
325 } 456 }
326 457
327 void NonClientFrameController::OnWindowDestroyed(ui::Window* window) { 458 void NonClientFrameController::OnWindowDestroyed(ui::Window* window) {
328 window_->RemoveObserver(this); 459 window_->RemoveObserver(this);
329 window_ = nullptr; 460 window_ = nullptr;
330 } 461 }
331 462
332 } // namespace mus 463 } // namespace mus
333 } // namespace ash 464 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698