diff options
Diffstat (limited to 'components/exo/shell_surface.cc')
| -rw-r--r-- | components/exo/shell_surface.cc | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc new file mode 100644 index 0000000..0e7e90a --- /dev/null +++ b/components/exo/shell_surface.cc @@ -0,0 +1,164 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/exo/shell_surface.h" + +#include "ash/shell.h" +#include "ash/shell_window_ids.h" +#include "base/logging.h" +#include "base/strings/utf_string_conversions.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_argument.h" +#include "components/exo/surface.h" +#include "ui/aura/window.h" +#include "ui/base/hit_test.h" +#include "ui/views/widget/widget.h" + +namespace exo { +namespace { + +class CustomFrameView : public views::NonClientFrameView { + public: + explicit CustomFrameView(views::Widget* widget) : widget_(widget) {} + ~CustomFrameView() override {} + + // Overridden from views::NonClientFrameView: + gfx::Rect GetBoundsForClientView() const override { return bounds(); } + gfx::Rect GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const override { + return client_bounds; + } + int NonClientHitTest(const gfx::Point& point) override { + return widget_->client_view()->NonClientHitTest(point); + } + void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {} + void ResetWindowControls() override {} + void UpdateWindowIcon() override {} + void UpdateWindowTitle() override {} + void SizeConstraintsChanged() override {} + + private: + views::Widget* const widget_; + + DISALLOW_COPY_AND_ASSIGN(CustomFrameView); +}; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// ShellSurface, public: + +ShellSurface::ShellSurface(Surface* surface) + : surface_(surface), show_state_(ui::SHOW_STATE_END) { + surface_->SetSurfaceDelegate(this); +} + +ShellSurface::~ShellSurface() { + if (surface_) + surface_->SetSurfaceDelegate(nullptr); + if (widget_) + widget_->CloseNow(); +} + +void ShellSurface::Show() { + TRACE_EVENT0("exo", "ShellSurface::Show"); + + if (!widget_ && show_state_ == ui::SHOW_STATE_END) + show_state_ = ui::SHOW_STATE_DEFAULT; +} + +void ShellSurface::SetToplevel() { + TRACE_EVENT0("exo", "ShellSurface::SetToplevel"); + + if (!widget_) + show_state_ = ui::SHOW_STATE_NORMAL; +} + +void ShellSurface::SetFullscreen(bool fullscreen) { + TRACE_EVENT1("exo", "ShellSurface::SetFullscreen", "fullscreen", fullscreen); + + if (widget_) { + widget_->SetFullscreen(fullscreen); + return; + } + + show_state_ = fullscreen ? ui::SHOW_STATE_FULLSCREEN : ui::SHOW_STATE_DEFAULT; +} + +void ShellSurface::SetTitle(const base::string16& title) { + TRACE_EVENT1("exo", "ShellSurface::SetTitle", "title", + base::UTF16ToUTF8(title)); + + title_ = title; + if (widget_) + widget_->UpdateWindowTitle(); +} + +scoped_refptr<base::trace_event::TracedValue> ShellSurface::AsTracedValue() + const { + scoped_refptr<base::trace_event::TracedValue> value = + new base::trace_event::TracedValue; + value->SetString("title", base::UTF16ToUTF8(title_)); + return value; +} + +//////////////////////////////////////////////////////////////////////////////// +// SurfaceDelegate overrides: + +void ShellSurface::OnSurfaceDestroying() { + surface_ = nullptr; +} + +void ShellSurface::OnSurfaceCommit() { + if (widget_ || show_state_ == ui::SHOW_STATE_END) + return; + + views::Widget::InitParams params; + params.type = views::Widget::InitParams::TYPE_WINDOW; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.delegate = this; + params.shadow_type = show_state_ == ui::SHOW_STATE_NORMAL + ? views::Widget::InitParams::SHADOW_TYPE_DROP + : views::Widget::InitParams::SHADOW_TYPE_NONE; + params.opacity = show_state_ == ui::SHOW_STATE_NORMAL + ? views::Widget::InitParams::OPAQUE_WINDOW + : views::Widget::InitParams::TRANSLUCENT_WINDOW; + params.show_state = show_state_; + params.parent = ash::Shell::GetContainer( + ash::Shell::GetPrimaryRootWindow(), ash::kShellWindowId_DefaultContainer); + widget_.reset(new views::Widget); + widget_->Init(params); + widget_->GetNativeWindow()->set_owned_by_parent(false); + widget_->GetNativeView()->SetName("ShellSurface"); + widget_->Show(); +} + +//////////////////////////////////////////////////////////////////////////////// +// views::WidgetDelegate overrides: + +base::string16 ShellSurface::GetWindowTitle() const { + return title_; +} + +views::Widget* ShellSurface::GetWidget() { + return widget_.get(); +} + +const views::Widget* ShellSurface::GetWidget() const { + return widget_.get(); +} + +views::View* ShellSurface::GetContentsView() { + return surface_; +} + +views::NonClientFrameView* ShellSurface::CreateNonClientFrameView( + views::Widget* widget) { + // Default show state is borderless and requires a custom frame view as the + // default one does not support this. + return show_state_ != ui::SHOW_STATE_NORMAL ? new CustomFrameView(widget) + : nullptr; +} + +} // namespace exo |
