Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1942)

Unified Diff: ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.cc

Issue 2027943002: [WIP] Make content_shell run under Wayland Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: (09.28.2016)Rebase on master Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_window_tree_host_wayland.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698