| 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..070f2b27ffa2d941c0396fbb939623a263f52144 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,109 @@ 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 {
|
| + CreateTitleAreaWindow();
|
| + SetVisibleFraction(0);
|
| + }
|
| + void OnImmersiveRevealEnded() override { DestroyTitleAreaWindow(); }
|
| + void OnImmersiveFullscreenExited() override { DestroyTitleAreaWindow(); }
|
| + void SetVisibleFraction(double visible_fraction) override {
|
| + 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());
|
| + // The intersection is in the coordinates of |title_area_window_|'s parent,
|
| + // convert to be in |title_area_window_| and then to screen.
|
| + visible_bounds -= title_area_window_->bounds().origin().OffsetFromOrigin();
|
| + // TODO: this needs updating when parent of |title_area_window| is changed,
|
| + // DCHECK is to ensure when parent changes this code is updated.
|
| + // http://crbug.com/640392.
|
| + DCHECK_EQ(frame_window_->parent(), title_area_window_->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, see also comment in GetVisibleBoundsInScreen().
|
| + 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 +232,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 +267,8 @@ class WmNativeWidgetMus : public views::NativeWidgetMus {
|
|
|
| ui::WindowManagerClient* window_manager_client_;
|
|
|
| + std::unique_ptr<ImmersiveFullscreenControllerDelegateMus> immersive_delegate_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(WmNativeWidgetMus);
|
| };
|
|
|
| @@ -190,12 +307,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 +332,6 @@ int NonClientFrameController::GetMaxTitleBarButtonWidth() {
|
| }
|
|
|
| NonClientFrameController::NonClientFrameController(
|
| - shell::Connector* connector,
|
| ui::Window* parent,
|
| ui::Window* window,
|
| ui::WindowManagerClient* window_manager_client)
|
| @@ -254,6 +368,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 +426,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)) {
|
| + return;
|
| + }
|
| + 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,
|
|
|