| Index: ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.cc
|
| diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..349cfaa365e7a31462c2c8c50d50c4d01c9781f9
|
| --- /dev/null
|
| +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.cc
|
| @@ -0,0 +1,778 @@
|
| +// Copyright 2016 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 "ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.h"
|
| +
|
| +#include "ui/aura/client/focus_client.h"
|
| +#include "ui/aura/window.h"
|
| +#include "ui/aura/window_property.h"
|
| +#include "ui/aura/window_tree_host.h"
|
| +#include "ui/display/screen.h"
|
| +#include "ui/native_theme/native_theme_aura.h"
|
| +#include "ui/ozone/public/ozone_platform.h"
|
| +#include "ui/views/corewm/tooltip_aura.h"
|
| +#include "ui/views/linux_ui/linux_ui.h"
|
| +#include "ui/views/views_delegate.h"
|
| +#include "ui/views/views_export.h"
|
| +#include "ui/views/views_switches.h"
|
| +#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_wayland.h"
|
| +#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
| +#include "ui/views/widget/desktop_aura/desktop_screen_wayland.h"
|
| +#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
|
| +#include "ui/wm/core/window_util.h"
|
| +#include "ui/wm/public/window_move_client.h"
|
| +
|
| +namespace views {
|
| +
|
| +std::list<gfx::AcceleratedWidget>*
|
| +DesktopWindowTreeHostWayland::open_windows_ = NULL;
|
| +
|
| +std::vector<aura::Window*>*
|
| +DesktopWindowTreeHostWayland::aura_windows_ = NULL;
|
| +
|
| +DesktopWindowTreeHostWayland::DesktopWindowTreeHostWayland(
|
| + internal::NativeWidgetDelegate* native_widget_delegate,
|
| + DesktopNativeWidgetAura* desktop_native_widget_aura)
|
| + : aura::WindowTreeHost(),
|
| + state_(Uninitialized),
|
| + window_(0),
|
| + title_(base::string16()),
|
| + drag_drop_client_(nullptr),
|
| + native_widget_delegate_(native_widget_delegate),
|
| + content_window_(nullptr),
|
| + desktop_native_widget_aura_(desktop_native_widget_aura),
|
| + window_parent_(nullptr),
|
| + window_children_(),
|
| + close_widget_factory_(this) {
|
| +}
|
| +
|
| +DesktopWindowTreeHostWayland::~DesktopWindowTreeHostWayland() {
|
| + aura::client::SetWindowMoveClient(window(), NULL);
|
| + desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
|
| + DestroyDispatcher();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::CleanUpWindowList() {
|
| + delete open_windows_;
|
| + open_windows_ = NULL;
|
| + if (aura_windows_) {
|
| + aura_windows_->clear();
|
| + delete aura_windows_;
|
| + aura_windows_ = NULL;
|
| + }
|
| +}
|
| +
|
| +gfx::Rect DesktopWindowTreeHostWayland::GetBoundsInScreen() const {
|
| + return platform_window_->GetBounds();
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// DesktopWindowTreeHostWayland, DesktopWindowTreeHost implementation:
|
| +
|
| +void DesktopWindowTreeHostWayland::Init(
|
| + aura::Window* content_window,
|
| + const Widget::InitParams& params) {
|
| + content_window_ = content_window;
|
| + // In some situations, views tries to make a zero sized window, and that
|
| + // makes us crash. Make sure we have valid sizes.
|
| + Widget::InitParams sanitized_params = params;
|
| + if (sanitized_params.bounds.width() == 0)
|
| + sanitized_params.bounds.set_width(100);
|
| + if (sanitized_params.bounds.height() == 0)
|
| + sanitized_params.bounds.set_height(100);
|
| +
|
| + platform_window_ =
|
| + ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this,
|
| + sanitized_params.bounds);
|
| + DCHECK(window_);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnNativeWidgetCreated(
|
| + const Widget::InitParams& params) {
|
| + // If we're given a parent, we need to mark ourselves as transient to another
|
| + // window. Otherwise activation gets screwy.
|
| + gfx::NativeView parent = params.parent;
|
| + if (!params.child && params.parent)
|
| + wm::AddTransientChild(parent, content_window_);
|
| +
|
| + native_widget_delegate_->OnNativeWidgetCreated(true);
|
| + open_windows().push_back(window_);
|
| + if (aura_windows_) {
|
| + aura_windows_->clear();
|
| + delete aura_windows_;
|
| + aura_windows_ = NULL;
|
| + }
|
| +}
|
| +
|
| +std::unique_ptr<corewm::Tooltip>
|
| +DesktopWindowTreeHostWayland::CreateTooltip() {
|
| + return std::unique_ptr<views::corewm::Tooltip>(
|
| + new views::corewm::TooltipAura);
|
| +}
|
| +
|
| +std::unique_ptr<aura::client::DragDropClient>
|
| +DesktopWindowTreeHostWayland::CreateDragDropClient(
|
| + DesktopNativeCursorManager* cursor_manager) {
|
| + //return base::WrapUnique(drag_drop_client_);
|
| + return base::WrapUnique(drag_drop_client_);
|
| +}
|
| +
|
| +
|
| +void DesktopWindowTreeHostWayland::Close() {
|
| + if (!close_widget_factory_.HasWeakPtrs()) {
|
| + // And we delay the close so that if we are called from an ATL callback,
|
| + // we don't destroy the window before the callback returned (as the caller
|
| + // may delete ourselves on destroy and the ATL callback would still
|
| + // dereference us when the callback returns).
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&DesktopWindowTreeHostWayland::CloseNow,
|
| + close_widget_factory_.GetWeakPtr()));
|
| + }
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::CloseNow() {
|
| + if (!window_)
|
| + return;
|
| +
|
| + unsigned widgetId = window_;
|
| + ReleaseCapture();
|
| + native_widget_delegate_->OnNativeWidgetDestroying();
|
| +
|
| + // If we have children, close them. Use a copy for iteration because they'll
|
| + // remove themselves.
|
| + std::set<DesktopWindowTreeHostWayland*> window_children_copy =
|
| + window_children_;
|
| + for (std::set<DesktopWindowTreeHostWayland*>::iterator it =
|
| + window_children_copy.begin(); it != window_children_copy.end();
|
| + ++it) {
|
| + (*it)->CloseNow();
|
| + }
|
| + DCHECK(window_children_.empty());
|
| +
|
| + // If we have a parent, remove ourselves from its children list.
|
| + if (window_parent_) {
|
| + window_parent_->window_children_.erase(this);
|
| + window_parent_ = NULL;
|
| + }
|
| +
|
| + // Destroy the compositor before destroying the window since shutdown
|
| + // may try to swap, and the swap without a window causes an X error, which
|
| + // causes a crash with in-process renderer.
|
| + DestroyCompositor();
|
| +
|
| + open_windows().remove(widgetId);
|
| + if (aura_windows_) {
|
| + aura_windows_->clear();
|
| + delete aura_windows_;
|
| + aura_windows_ = NULL;
|
| + }
|
| +
|
| + // Actually free our native resources.
|
| + platform_window_->Close();
|
| + window_ = 0;
|
| + if (open_windows().empty())
|
| + CleanUpWindowList();
|
| +
|
| + desktop_native_widget_aura_->OnHostClosed();
|
| +}
|
| +
|
| +
|
| +aura::WindowTreeHost* DesktopWindowTreeHostWayland::AsWindowTreeHost() {
|
| + return this;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::ShowWindowWithState(
|
| + ui::WindowShowState show_state) {
|
| + if (compositor())
|
| + compositor()->SetVisible(true);
|
| + state_ |= Visible;
|
| +
|
| + switch (show_state) {
|
| + case ui::SHOW_STATE_NORMAL:
|
| + Activate();
|
| + break;
|
| + case ui::SHOW_STATE_MAXIMIZED:
|
| + Maximize();
|
| + break;
|
| + case ui::SHOW_STATE_MINIMIZED:
|
| + Minimize();
|
| + break;
|
| + case ui::SHOW_STATE_FULLSCREEN:
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| +
|
| + native_widget_delegate_->AsWidget()->SetInitialFocus(show_state);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::ShowMaximizedWithBounds(
|
| + const gfx::Rect& restored_bounds) {
|
| + ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED);
|
| + previous_bounds_ = restored_bounds;
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::IsVisible() const {
|
| + return state_ & Visible;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetSize(const gfx::Size& requested_size) {
|
| + gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size();
|
| + size_in_pixels = AdjustSize(size_in_pixels);
|
| + gfx::Rect new_bounds = platform_window_->GetBounds();
|
| + new_bounds.set_size(size_in_pixels);
|
| + platform_window_->SetBounds(new_bounds);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::StackAbove(aura::Window* window) {
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::StackAtTop() {
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::CenterWindow(const gfx::Size& size) {
|
| + gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(size)).size();
|
| + gfx::Rect parent_bounds_in_pixels = GetWorkAreaBoundsInScreen();
|
| +
|
| + // If |window_|'s transient parent bounds are big enough to contain |size|,
|
| + // use them instead.
|
| + if (wm::GetTransientParent(content_window_)) {
|
| + gfx::Rect transient_parent_rect =
|
| + wm::GetTransientParent(content_window_)->GetBoundsInScreen();
|
| + if (transient_parent_rect.height() >= size.height() &&
|
| + transient_parent_rect.width() >= size.width()) {
|
| + parent_bounds_in_pixels = ToPixelRect(transient_parent_rect);
|
| + }
|
| + }
|
| +
|
| + gfx::Rect window_bounds_in_pixels(
|
| + parent_bounds_in_pixels.x() +
|
| + (parent_bounds_in_pixels.width() - size_in_pixels.width()) / 2,
|
| + parent_bounds_in_pixels.y() +
|
| + (parent_bounds_in_pixels.height() - size_in_pixels.height()) / 2,
|
| + size_in_pixels.width(), size_in_pixels.height());
|
| + // Don't size the window bigger than the parent, otherwise the user may not be
|
| + // able to close or move it.
|
| + window_bounds_in_pixels.AdjustToFit(parent_bounds_in_pixels);
|
| +
|
| + SetBounds(window_bounds_in_pixels);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::GetWindowPlacement(
|
| + gfx::Rect* bounds,
|
| + ui::WindowShowState* show_state) const {
|
| + *bounds = GetRestoredBounds();
|
| +
|
| + if (IsMinimized()) {
|
| + *show_state = ui::SHOW_STATE_MINIMIZED;
|
| + } else if (IsFullscreen()) {
|
| + *show_state = ui::SHOW_STATE_FULLSCREEN;
|
| + } else if (IsMaximized()) {
|
| + *show_state = ui::SHOW_STATE_MAXIMIZED;
|
| + } else if (!IsActive()) {
|
| + *show_state = ui::SHOW_STATE_INACTIVE;
|
| + } else {
|
| + *show_state = ui::SHOW_STATE_NORMAL;
|
| + }
|
| +}
|
| +
|
| +gfx::Rect DesktopWindowTreeHostWayland::GetWindowBoundsInScreen() const {
|
| + return platform_window_->GetBounds();
|
| +}
|
| +
|
| +gfx::Rect DesktopWindowTreeHostWayland::GetClientAreaBoundsInScreen() const {
|
| + // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its
|
| + // needed for View::ConvertPointToScreen() to work
|
| + // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just
|
| + // asks windows what it thinks the client rect is.
|
| + //
|
| + // Attempts to calculate the rect by asking the NonClientFrameView what it
|
| + // thought its GetBoundsForClientView() were broke combobox drop down
|
| + // placement.
|
| + return platform_window_->GetBounds();
|
| +}
|
| +
|
| +gfx::Rect DesktopWindowTreeHostWayland::GetRestoredBounds() const {
|
| + if (!previous_bounds_.IsEmpty())
|
| + return ToDIPRect(previous_bounds_);
|
| +
|
| + return GetWindowBoundsInScreen();
|
| +}
|
| +
|
| +std::string DesktopWindowTreeHostWayland::GetWorkspace() const {
|
| + return std::string();
|
| +}
|
| +
|
| +gfx::Rect DesktopWindowTreeHostWayland::GetWorkAreaBoundsInScreen() const {
|
| + display::Screen *screen = display::Screen::GetScreen();
|
| + if (!screen)
|
| + NOTREACHED() << "Unable to retrieve valid display::Screen";
|
| +
|
| + display::Display display = screen->GetPrimaryDisplay();
|
| + return ToDIPRect(display.bounds());
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetShape(SkRegion* native_region) {
|
| + // NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::Activate() {
|
| + if (state_ & Visible) {
|
| + OnActivationChanged(true);
|
| + }
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::Deactivate() {
|
| + OnActivationChanged(false);
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::IsActive() const {
|
| + return state_ & Active;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::Maximize() {
|
| + if (state_ & Maximized)
|
| + return;
|
| +
|
| + state_ |= Maximized;
|
| + state_ &= ~Minimized;
|
| + previous_bounds_ = platform_window_->GetBounds();
|
| + platform_window_->Maximize();
|
| + if (IsMinimized())
|
| + ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::Minimize() {
|
| + if (state_ & Minimized)
|
| + return;
|
| +
|
| + state_ |= Minimized;
|
| + previous_bounds_ = platform_window_->GetBounds();
|
| + ReleaseCapture();
|
| + compositor()->SetVisible(false);
|
| + content_window_->Hide();
|
| + platform_window_->Minimize();
|
| + Relayout();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::Restore() {
|
| + state_ &= ~Maximized;
|
| + if (state_ & Minimized) {
|
| + content_window_->Show();
|
| + compositor()->SetVisible(true);
|
| + }
|
| +
|
| + platform_window_->Restore();
|
| + platform_window_->SetBounds(previous_bounds_);
|
| + previous_bounds_ = gfx::Rect();
|
| + Relayout();
|
| + if (state_ & Minimized) {
|
| + state_ &= ~Minimized;
|
| + ShowWindow();
|
| + }
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::IsMaximized() const {
|
| + return !IsFullscreen() && (state_ & Maximized);
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::IsMinimized() const {
|
| + return state_ & Minimized;
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::HasCapture() const {
|
| + return has_capture_;
|
| +}
|
| +
|
| +
|
| +void DesktopWindowTreeHostWayland::SetAlwaysOnTop(bool always_on_top) {
|
| + always_on_top_ = always_on_top;
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::IsAlwaysOnTop() const {
|
| + return always_on_top_;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetVisibleOnAllWorkspaces(
|
| + bool always_visible) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::SetWindowTitle(const base::string16& title) {
|
| + if (title.compare(title_)) {
|
| + platform_window_->SetTitle(title);
|
| + title_ = title;
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::ClearNativeFocus() {
|
| + // This method is weird and misnamed. Instead of clearing the native focus,
|
| + // it sets the focus to our |content_window_|, which will trigger a cascade
|
| + // of focus changes into views.
|
| + if (content_window_ && aura::client::GetFocusClient(content_window_) &&
|
| + content_window_->Contains(
|
| + aura::client::GetFocusClient(content_window_)->GetFocusedWindow())) {
|
| + aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_);
|
| + }
|
| +}
|
| +
|
| +Widget::MoveLoopResult DesktopWindowTreeHostWayland::RunMoveLoop(
|
| + const gfx::Vector2d& drag_offset,
|
| + Widget::MoveLoopSource source,
|
| + Widget::MoveLoopEscapeBehavior escape_behavior) {
|
| + NOTIMPLEMENTED();
|
| + return Widget::MOVE_LOOP_SUCCESSFUL;
|
| +}
|
| +
|
| +
|
| +void DesktopWindowTreeHostWayland::EndMoveLoop() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetVisibilityChangedAnimationsEnabled(
|
| + bool value) {
|
| + // Much like the previous NativeWidgetGtk, we don't have anything to do here.
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::ShouldUseNativeFrame() const {
|
| + return false;
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::ShouldWindowContentsBeTransparent() const {
|
| + return false;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::FrameTypeChanged() {
|
| + Widget::FrameType new_type =
|
| + native_widget_delegate_->AsWidget()->frame_type();
|
| + if (new_type == Widget::FRAME_TYPE_DEFAULT) {
|
| + // The default is determined by Widget::InitParams::remove_standard_frame
|
| + // and does not change.
|
| + return;
|
| + }
|
| +
|
| + // Replace the frame and layout the contents. Even though we don't have a
|
| + // swapable glass frame like on Windows, we still replace the frame because
|
| + // the button assets don't update otherwise.
|
| + native_widget_delegate_->AsWidget()->non_client_view()->UpdateFrame();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetFullscreen(bool fullscreen) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::IsFullscreen() const {
|
| + return state_ & FullScreen;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetOpacity(float opacity) {
|
| + content_window_->layer()->SetOpacity(opacity / 255.0);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetWindowIcons(
|
| + const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::InitModalType(ui::ModalType modal_type) {
|
| + switch (modal_type) {
|
| + case ui::MODAL_TYPE_NONE:
|
| + break;
|
| + default:
|
| + // TODO(erg): Figure out under what situations |modal_type| isn't
|
| + // none. The comment in desktop_native_widget_aura.cc suggests that this
|
| + // is rare.
|
| + NOTIMPLEMENTED();
|
| + }
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::FlashFrame(bool flash_frame) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnRootViewLayout() {
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnNativeWidgetFocus() {
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnNativeWidgetBlur() {
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::IsAnimatingClosed() const {
|
| + return false;
|
| +}
|
| +
|
| +bool DesktopWindowTreeHostWayland::IsTranslucentWindowOpacitySupported() const {
|
| + return false;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SizeConstraintsChanged() {
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// DesktopWindowTreeHostWayland, aura::WindowTreeHost implementation:
|
| +
|
| +gfx::Transform DesktopWindowTreeHostWayland::GetRootTransform() const {
|
| + display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
|
| + aura::Window* win = const_cast<aura::Window*>(window());
|
| + display = display::Screen::GetScreen()->GetDisplayNearestWindow(win);
|
| +
|
| + float scale = display.device_scale_factor();
|
| + gfx::Transform transform;
|
| + transform.Scale(scale, scale);
|
| + return transform;
|
| +}
|
| +
|
| +ui::EventSource* DesktopWindowTreeHostWayland::GetEventSource() {
|
| + return this;
|
| +}
|
| +
|
| +gfx::AcceleratedWidget DesktopWindowTreeHostWayland::GetAcceleratedWidget() {
|
| + return window_;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::ShowImpl() {
|
| + if (state_ & Visible)
|
| + return;
|
| +
|
| + ShowWindowWithState(ui::SHOW_STATE_NORMAL);
|
| + native_widget_delegate_->OnNativeWidgetVisibilityChanged(true);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::HideImpl() {
|
| + if (!(state_ & Visible))
|
| + return;
|
| +
|
| + state_ &= ~Visible;
|
| + platform_window_->Hide();
|
| + native_widget_delegate_->OnNativeWidgetVisibilityChanged(false);
|
| +}
|
| +
|
| +gfx::Rect DesktopWindowTreeHostWayland::GetBounds() const {
|
| + return platform_window_->GetBounds();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetBounds(
|
| + const gfx::Rect& requested_bounds) {
|
| + gfx::Rect bounds(requested_bounds.origin(),
|
| + AdjustSize(requested_bounds.size()));
|
| + platform_window_->SetBounds(bounds);
|
| +}
|
| +
|
| +gfx::Point DesktopWindowTreeHostWayland::GetLocationOnNativeScreen() const {
|
| + return platform_window_->GetBounds().origin();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetCapture() {
|
| + if (has_capture_)
|
| + return;
|
| +
|
| + has_capture_ = true;
|
| + platform_window_->SetCapture();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::ReleaseCapture() {
|
| + platform_window_->ReleaseCapture();
|
| + OnLostCapture();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::ShowWindow() {
|
| + ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL;
|
| + if (IsMinimized()) {
|
| + show_state = ui::SHOW_STATE_MINIMIZED;
|
| + } else if (IsFullscreen()) {
|
| + show_state = ui::SHOW_STATE_FULLSCREEN;
|
| + } else if (IsMaximized()) {
|
| + show_state = ui::SHOW_STATE_MAXIMIZED;
|
| + } else if (!IsActive()) {
|
| + show_state = ui::SHOW_STATE_INACTIVE;
|
| + }
|
| +
|
| + ShowWindowWithState(show_state);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::SetCursorNative(gfx::NativeCursor cursor) {
|
| + platform_window_->SetCursor(cursor.platform());
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::MoveCursorToNative(
|
| + const gfx::Point& location) {
|
| + platform_window_->MoveCursorTo(location);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnCursorVisibilityChangedNative(bool show) {
|
| + // TODO(erg): Conditional on us enabling touch on desktop linux builds, do
|
| + // the same tap-to-click disabling here that chromeos does.
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// ui::PlatformWindowDelegate implementation:
|
| +void DesktopWindowTreeHostWayland::OnBoundsChanged(
|
| + const gfx::Rect& new_bounds) {
|
| +
|
| + native_widget_delegate_->AsWidget()->OnNativeWidgetMove();
|
| + OnHostResized(new_bounds.size());
|
| + ResetWindowRegion();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnDamageRect(const gfx::Rect& damaged_rect) {
|
| + compositor()->ScheduleRedrawRect(damaged_rect);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnAcceleratedWidgetDestroyed() {
|
| + gfx::AcceleratedWidget window = compositor()->ReleaseAcceleratedWidget();
|
| + DCHECK_EQ(window, window_);
|
| + window_ = gfx::kNullAcceleratedWidget;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnActivationChanged(bool active) {
|
| + if (active == (state_ & Active))
|
| + return;
|
| +
|
| + if (active) {
|
| + // Make sure the stacking order is correct. The activated window should be
|
| + // first one in list of open windows.
|
| + std::list<gfx::AcceleratedWidget>& windows = open_windows();
|
| + DCHECK(windows.size());
|
| + if (windows.front() != window_) {
|
| + windows.remove(window_);
|
| + windows.insert(windows.begin(), window_);
|
| + }
|
| +
|
| + state_ |= Active;
|
| + OnHostActivated();
|
| + } else {
|
| + state_ &= ~Active;
|
| + ReleaseCapture();
|
| + }
|
| +
|
| + desktop_native_widget_aura_->HandleActivationChanged(active);
|
| + native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint();
|
| +}
|
| +
|
| +
|
| +void DesktopWindowTreeHostWayland::OnLostCapture() {
|
| + OnHostLostWindowCapture();
|
| + has_capture_ = false;
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnAcceleratedWidgetAvailable(
|
| + gfx::AcceleratedWidget widget,
|
| + float device_pixel_ratio) {
|
| + window_ = widget;
|
| + CreateCompositor();
|
| + WindowTreeHost::OnAcceleratedWidgetAvailable();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnCloseRequest() {
|
| + Close();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnClosed() {
|
| + CloseNow();
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::OnWindowStateChanged(
|
| + ui::PlatformWindowState new_state) {
|
| +
|
| + switch (new_state) {
|
| + case ui::PLATFORM_WINDOW_STATE_MAXIMIZED: {
|
| + if (state_ & Minimized) {
|
| + content_window_->Show();
|
| + compositor()->SetVisible(true);
|
| + state_ &= ~Minimized;
|
| + }
|
| + platform_window_->SetBounds(previous_bounds_);
|
| + previous_bounds_ = gfx::Rect();
|
| + Relayout();
|
| + break;
|
| + }
|
| + default:
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::DispatchEvent(ui::Event* event) {
|
| + SendEventToProcessor(event);
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// DesktopWindowTreeHostWayland, private:
|
| +
|
| +void DesktopWindowTreeHostWayland::Relayout() {
|
| + Widget* widget = native_widget_delegate_->AsWidget();
|
| + NonClientView* non_client_view = widget->non_client_view();
|
| + // non_client_view may be NULL, especially during creation.
|
| + if (non_client_view) {
|
| + non_client_view->client_view()->InvalidateLayout();
|
| + non_client_view->InvalidateLayout();
|
| + }
|
| + widget->GetRootView()->Layout();
|
| + ResetWindowRegion();
|
| +}
|
| +
|
| +std::list<gfx::AcceleratedWidget>&
|
| +DesktopWindowTreeHostWayland::open_windows() {
|
| + if (!open_windows_)
|
| + open_windows_ = new std::list<gfx::AcceleratedWidget>();
|
| + return *open_windows_;
|
| +}
|
| +
|
| +gfx::Size DesktopWindowTreeHostWayland::AdjustSize(
|
| + const gfx::Size& requested_size_in_pixels) {
|
| +
|
| + std::vector<display::Display> displays =
|
| + display::Screen::GetScreen()->GetAllDisplays();
|
| + // Compare against all monitor sizes. The window manager can move the window
|
| + // to whichever monitor it wants.
|
| + for (size_t i = 0; i < displays.size(); ++i) {
|
| + if (requested_size_in_pixels == displays[i].GetSizeInPixel()) {
|
| + return gfx::Size(requested_size_in_pixels.width() - 1,
|
| + requested_size_in_pixels.height() - 1);
|
| + }
|
| + }
|
| +
|
| + // Do not request a 0x0 window size.
|
| + gfx::Size size_in_pixels = requested_size_in_pixels;
|
| + size_in_pixels.SetToMax(gfx::Size(1, 1));
|
| + return size_in_pixels;
|
| +}
|
| +
|
| +gfx::Rect DesktopWindowTreeHostWayland::ToDIPRect(
|
| + const gfx::Rect& rect_in_pixels) const {
|
| + gfx::RectF rect_in_dip = gfx::RectF(rect_in_pixels);
|
| + GetRootTransform().TransformRectReverse(&rect_in_dip);
|
| + return gfx::ToEnclosingRect(rect_in_dip);
|
| +}
|
| +
|
| +gfx::Rect DesktopWindowTreeHostWayland::ToPixelRect(
|
| + const gfx::Rect& rect_in_dip) const {
|
| + gfx::RectF rect_in_pixels = gfx::RectF(rect_in_dip);
|
| + GetRootTransform().TransformRect(&rect_in_pixels);
|
| + return gfx::ToEnclosingRect(rect_in_pixels);
|
| +}
|
| +
|
| +void DesktopWindowTreeHostWayland::ResetWindowRegion() {
|
| + if (custom_window_shape_)
|
| + return;
|
| +
|
| + gfx::Path window_mask;
|
| + const gfx::Rect& bounds_in_pixels = platform_window_->GetBounds();
|
| + if (!IsMaximized() && !IsFullscreen()) {
|
| + views::Widget* widget = native_widget_delegate_->AsWidget();
|
| + if (widget->non_client_view()) {
|
| + // Some frame views define a custom (non-rectangular) window mask. If
|
| + // so, use it to define the window shape. If not, fall through.
|
| + widget->non_client_view()->GetWindowMask(bounds_in_pixels.size(),
|
| + &window_mask);
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace views
|
|
|