Chromium Code Reviews| Index: ash/mus/non_client_frame_controller.cc |
| diff --git a/ash/mus/non_client_frame_controller.cc b/ash/mus/non_client_frame_controller.cc |
| index 1f46aa8c23255f2854162a9f5b9e5df11e7cf150..2f5f787c52f17dc1a6f6526a37fd213b51e26ff4 100644 |
| --- a/ash/mus/non_client_frame_controller.cc |
| +++ b/ash/mus/non_client_frame_controller.cc |
| @@ -14,15 +14,19 @@ |
| #include "ash/common/ash_layout_constants.h" |
| #include "ash/common/frame/custom_frame_view_ash.h" |
| #include "ash/mus/bridge/wm_window_mus.h" |
| +#include "ash/mus/frame/custom_frame_view_mus.h" |
| +#include "ash/mus/frame/detached_title_area_renderer.h" |
| #include "ash/mus/move_event_handler.h" |
| #include "ash/mus/property_util.h" |
| #include "ash/mus/shadow.h" |
| +#include "ash/shared/immersive_fullscreen_controller_delegate.h" |
| #include "base/macros.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "services/ui/public/cpp/property_type_converters.h" |
| #include "services/ui/public/cpp/window.h" |
| #include "services/ui/public/cpp/window_manager_delegate.h" |
| #include "services/ui/public/cpp/window_property.h" |
| +#include "services/ui/public/cpp/window_tree_client.h" |
| #include "services/ui/public/interfaces/window_manager.mojom.h" |
| #include "services/ui/public/interfaces/window_tree_host.mojom.h" |
| #include "ui/aura/layout_manager.h" |
| @@ -110,6 +114,105 @@ class EmptyDraggableNonClientFrameView : public views::NonClientFrameView { |
| DISALLOW_COPY_AND_ASSIGN(EmptyDraggableNonClientFrameView); |
| }; |
| +// Creates a ui::Window to host the top container when in immersive mode. The |
| +// top container contains a DetachedTitleAreaRenderer, which handles drawing and |
| +// events. |
| +class ImmersiveFullscreenControllerDelegateMus |
| + : public ImmersiveFullscreenControllerDelegate, |
| + public DetachedTitleAreaRendererHost { |
| + public: |
| + ImmersiveFullscreenControllerDelegateMus(views::Widget* frame, |
| + ui::Window* frame_window) |
| + : frame_(frame), frame_window_(frame_window) {} |
| + ~ImmersiveFullscreenControllerDelegateMus() override { |
| + DestroyTitleAreaWindow(); |
| + } |
| + |
| + // WmImmersiveFullscreenControllerDelegate: |
| + 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.
|
| + void OnImmersiveRevealEnded() override { SetVisibleFraction(0); } |
| + void OnImmersiveFullscreenExited() override { SetVisibleFraction(0); } |
| + void SetVisibleFraction(double visible_fraction) override { |
| + if (visible_fraction == 0) { |
| + DestroyTitleAreaWindow(); |
| + return; |
| + } |
| + CreateTitleAreaWindow(); |
| + if (!title_area_window_) |
| + return; |
| + gfx::Rect bounds = title_area_window_->bounds(); |
| + bounds.set_y(frame_window_->bounds().y() - bounds.height() + |
| + visible_fraction * bounds.height()); |
| + title_area_window_->SetBounds(bounds); |
| + } |
| + std::vector<gfx::Rect> GetVisibleBoundsInScreen() const override { |
| + std::vector<gfx::Rect> result; |
| + if (!title_area_window_) |
| + return result; |
| + |
| + // Clip the bounds of the title area to that of the |frame_window_|. |
| + gfx::Rect visible_bounds = title_area_window_->bounds(); |
| + visible_bounds.Intersect(frame_window_->bounds()); |
| + 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
|
| + result.push_back(WmWindowMus::Get(title_area_window_) |
| + ->ConvertRectToScreen(visible_bounds)); |
| + return result; |
| + } |
| + |
| + // DetachedTitleAreaRendererHost: |
| + void OnDetachedTitleAreaRendererDestroyed( |
| + DetachedTitleAreaRenderer* renderer) override { |
| + title_area_renderer_ = nullptr; |
| + title_area_window_ = nullptr; |
| + } |
| + |
| + private: |
| + void CreateTitleAreaWindow() { |
| + if (title_area_window_) |
| + return; |
| + |
| + title_area_window_ = frame_window_->window_tree()->NewWindow(); |
| + // TODO(sky): bounds aren't right here. Need to convert to display. |
| + gfx::Rect bounds = frame_window_->bounds(); |
| + // Use the preferred size as when fullscreen the client area is generally |
| + // set to 0. |
| + bounds.set_height( |
| + NonClientFrameController::GetPreferredClientAreaInsets().top()); |
| + bounds.set_y(bounds.y() - bounds.height()); |
| + title_area_window_->SetBounds(bounds); |
| + // TODO: making the reveal window a sibling is likely problematic. |
| + // http://crbug.com/640392, |
| + frame_window_->parent()->AddChild(title_area_window_); |
| + title_area_window_->Reorder(frame_window_, |
| + ui::mojom::OrderDirection::ABOVE); |
| + title_area_renderer_ = |
| + new DetachedTitleAreaRenderer(this, frame_, title_area_window_, |
| + DetachedTitleAreaRenderer::Source::MASH); |
| + } |
| + |
| + void DestroyTitleAreaWindow() { |
| + if (!title_area_window_) |
| + return; |
| + title_area_renderer_->Destroy(); |
| + title_area_renderer_ = nullptr; |
| + // TitleAreaRevealer ends up owning window. |
| + title_area_window_ = nullptr; |
| + } |
| + |
| + // The Widget immersive mode is operating on. |
| + views::Widget* frame_; |
| + |
| + // The ui::Window associated with |frame_|. |
| + ui::Window* frame_window_; |
| + |
| + // The window hosting the title area. |
| + ui::Window* title_area_window_ = nullptr; |
| + |
| + DetachedTitleAreaRenderer* title_area_renderer_ = nullptr; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenControllerDelegateMus); |
| +}; |
| + |
| class WmNativeWidgetMus : public views::NativeWidgetMus { |
| public: |
| WmNativeWidgetMus(views::internal::NativeWidgetDelegate* delegate, |
| @@ -125,7 +228,15 @@ class WmNativeWidgetMus : public views::NativeWidgetMus { |
| window(), window_manager_client_, GetNativeView())); |
| if (ShouldRemoveStandardFrame(window())) |
| return new EmptyDraggableNonClientFrameView(); |
| - return new CustomFrameViewAsh(GetWidget()); |
| + immersive_delegate_.reset( |
| + new ImmersiveFullscreenControllerDelegateMus(GetWidget(), window())); |
| + const bool enable_immersive = |
| + !window()->HasSharedProperty( |
| + ui::mojom::WindowManager::kDisableImmersive_Property) || |
| + !window()->GetSharedProperty<bool>( |
| + ui::mojom::WindowManager::kDisableImmersive_Property); |
| + return new CustomFrameViewMus(GetWidget(), immersive_delegate_.get(), |
| + enable_immersive); |
| } |
| void InitNativeWidget(const views::Widget::InitParams& params) override { |
| views::NativeWidgetMus::InitNativeWidget(params); |
| @@ -152,6 +263,8 @@ class WmNativeWidgetMus : public views::NativeWidgetMus { |
| ui::WindowManagerClient* window_manager_client_; |
| + std::unique_ptr<ImmersiveFullscreenControllerDelegateMus> immersive_delegate_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(WmNativeWidgetMus); |
| }; |
| @@ -190,12 +303,10 @@ gfx::Insets GetExtendedHitRegion() { |
| // static |
| void NonClientFrameController::Create( |
| - shell::Connector* connector, |
| ui::Window* parent, |
| ui::Window* window, |
| ui::WindowManagerClient* window_manager_client) { |
| - new NonClientFrameController(connector, parent, window, |
| - window_manager_client); |
| + new NonClientFrameController(parent, window, window_manager_client); |
| } |
| // static |
| @@ -217,7 +328,6 @@ int NonClientFrameController::GetMaxTitleBarButtonWidth() { |
| } |
| NonClientFrameController::NonClientFrameController( |
| - shell::Connector* connector, |
| ui::Window* parent, |
| ui::Window* window, |
| ui::WindowManagerClient* window_manager_client) |
| @@ -254,6 +364,14 @@ NonClientFrameController::NonClientFrameController( |
| NonClientFrameController::~NonClientFrameController() { |
| if (window_) |
| window_->RemoveObserver(this); |
| + if (detached_title_area_renderer_) |
| + detached_title_area_renderer_->Destroy(); |
| +} |
| + |
| +void NonClientFrameController::OnDetachedTitleAreaRendererDestroyed( |
| + DetachedTitleAreaRenderer* renderer) { |
| + DCHECK_EQ(detached_title_area_renderer_, renderer); |
| + detached_title_area_renderer_ = nullptr; |
| } |
| base::string16 NonClientFrameController::GetWindowTitle() const { |
| @@ -304,6 +422,19 @@ views::ClientView* NonClientFrameController::CreateClientView( |
| return new ClientViewMus(widget, GetContentsView(), this); |
| } |
| +void NonClientFrameController::OnTreeChanged(const TreeChangeParams& params) { |
| + if (params.new_parent == window_ && |
| + ShouldRenderParentTitleArea(params.target)) { |
|
James Cook
2016/08/24 17:00:32
optional nit: early return?
sky
2016/08/24 19:23:29
Done.
|
| + if (detached_title_area_renderer_) { |
| + detached_title_area_renderer_->Destroy(); |
| + detached_title_area_renderer_ = nullptr; |
| + } |
| + detached_title_area_renderer_ = new DetachedTitleAreaRenderer( |
| + this, widget_, params.target, |
| + DetachedTitleAreaRenderer::Source::CLIENT); |
| + } |
| +} |
| + |
| void NonClientFrameController::OnWindowSharedPropertyChanged( |
| ui::Window* window, |
| const std::string& name, |