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..9b5cdf04ae2fde9e235ee30c2c1e028baad5ea03 |
--- /dev/null |
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.cc |
@@ -0,0 +1,781 @@ |
+// 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_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/drag_drop_client.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()), |
+ 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 nullptr; |
+} |
+ |
+ |
+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()->task_runner()->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(std::unique_ptr<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::IsVisibleOnAllWorkspaces() const { |
+ return false; |
+} |
+ |
+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 |