diff options
Diffstat (limited to 'headless/lib/browser/headless_screen.cc')
-rw-r--r-- | headless/lib/browser/headless_screen.cc | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/headless/lib/browser/headless_screen.cc b/headless/lib/browser/headless_screen.cc new file mode 100644 index 0000000..6d6f607 --- /dev/null +++ b/headless/lib/browser/headless_screen.cc @@ -0,0 +1,174 @@ +// 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 "headless/lib/browser/headless_screen.h" + +#include <stdint.h> + +#include "base/logging.h" +#include "ui/aura/env.h" +#include "ui/aura/window.h" +#include "ui/aura/window_event_dispatcher.h" +#include "ui/aura/window_tree_host.h" +#include "ui/base/ime/input_method.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/gfx/screen.h" + +namespace headless { + +namespace { + +bool IsRotationPortrait(gfx::Display::Rotation rotation) { + return rotation == gfx::Display::ROTATE_90 || + rotation == gfx::Display::ROTATE_270; +} + +} // namespace + +// static +HeadlessScreen* HeadlessScreen::Create(const gfx::Size& size) { + const gfx::Size kDefaultSize(800, 600); + return new HeadlessScreen(gfx::Rect(size.IsEmpty() ? kDefaultSize : size)); +} + +HeadlessScreen::~HeadlessScreen() {} + +aura::WindowTreeHost* HeadlessScreen::CreateHostForPrimaryDisplay() { + DCHECK(!host_); + host_ = aura::WindowTreeHost::Create(gfx::Rect(display_.GetSizeInPixel())); + // Some tests don't correctly manage window focus/activation states. + // Makes sure InputMethod is default focused so that IME basics can work. + host_->GetInputMethod()->OnFocus(); + host_->window()->AddObserver(this); + host_->InitHost(); + return host_; +} + +void HeadlessScreen::SetDeviceScaleFactor(float device_scale_factor) { + gfx::Rect bounds_in_pixel(display_.GetSizeInPixel()); + display_.SetScaleAndBounds(device_scale_factor, bounds_in_pixel); +} + +void HeadlessScreen::SetDisplayRotation(gfx::Display::Rotation rotation) { + gfx::Rect bounds_in_pixel(display_.GetSizeInPixel()); + gfx::Rect new_bounds(bounds_in_pixel); + if (IsRotationPortrait(rotation) != IsRotationPortrait(display_.rotation())) { + new_bounds.set_width(bounds_in_pixel.height()); + new_bounds.set_height(bounds_in_pixel.width()); + } + display_.set_rotation(rotation); + display_.SetScaleAndBounds(display_.device_scale_factor(), new_bounds); + host_->SetRootTransform(GetRotationTransform() * GetUIScaleTransform()); +} + +void HeadlessScreen::SetUIScale(float ui_scale) { + ui_scale_ = ui_scale; + gfx::Rect bounds_in_pixel(display_.GetSizeInPixel()); + gfx::Rect new_bounds = gfx::ToNearestRect( + gfx::ScaleRect(gfx::RectF(bounds_in_pixel), 1.0f / ui_scale)); + display_.SetScaleAndBounds(display_.device_scale_factor(), new_bounds); + host_->SetRootTransform(GetRotationTransform() * GetUIScaleTransform()); +} + +void HeadlessScreen::SetWorkAreaInsets(const gfx::Insets& insets) { + display_.UpdateWorkAreaFromInsets(insets); +} + +gfx::Transform HeadlessScreen::GetRotationTransform() const { + gfx::Transform rotate; + switch (display_.rotation()) { + case gfx::Display::ROTATE_0: + break; + case gfx::Display::ROTATE_90: + rotate.Translate(display_.bounds().height(), 0); + rotate.Rotate(90); + break; + case gfx::Display::ROTATE_270: + rotate.Translate(0, display_.bounds().width()); + rotate.Rotate(270); + break; + case gfx::Display::ROTATE_180: + rotate.Translate(display_.bounds().width(), display_.bounds().height()); + rotate.Rotate(180); + break; + } + + return rotate; +} + +gfx::Transform HeadlessScreen::GetUIScaleTransform() const { + gfx::Transform ui_scale; + ui_scale.Scale(1.0f / ui_scale_, 1.0f / ui_scale_); + return ui_scale; +} + +void HeadlessScreen::OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) { + DCHECK_EQ(host_->window(), window); + display_.SetSize(gfx::ScaleToFlooredSize(new_bounds.size(), + display_.device_scale_factor())); +} + +void HeadlessScreen::OnWindowDestroying(aura::Window* window) { + if (host_->window() == window) + host_ = NULL; +} + +gfx::Point HeadlessScreen::GetCursorScreenPoint() { + return aura::Env::GetInstance()->last_mouse_location(); +} + +gfx::NativeWindow HeadlessScreen::GetWindowUnderCursor() { + return GetWindowAtScreenPoint(GetCursorScreenPoint()); +} + +gfx::NativeWindow HeadlessScreen::GetWindowAtScreenPoint( + const gfx::Point& point) { + if (!host_ || !host_->window()) + return nullptr; + return host_->window()->GetTopWindowContainingPoint(point); +} + +int HeadlessScreen::GetNumDisplays() const { + return 1; +} + +std::vector<gfx::Display> HeadlessScreen::GetAllDisplays() const { + return std::vector<gfx::Display>(1, display_); +} + +gfx::Display HeadlessScreen::GetDisplayNearestWindow( + gfx::NativeWindow window) const { + return display_; +} + +gfx::Display HeadlessScreen::GetDisplayNearestPoint( + const gfx::Point& point) const { + return display_; +} + +gfx::Display HeadlessScreen::GetDisplayMatching( + const gfx::Rect& match_rect) const { + return display_; +} + +gfx::Display HeadlessScreen::GetPrimaryDisplay() const { + return display_; +} + +void HeadlessScreen::AddObserver(gfx::DisplayObserver* observer) {} + +void HeadlessScreen::RemoveObserver(gfx::DisplayObserver* observer) {} + +HeadlessScreen::HeadlessScreen(const gfx::Rect& screen_bounds) + : host_(NULL), ui_scale_(1.0f) { + static int64_t synthesized_display_id = 2000; + display_.set_id(synthesized_display_id++); + display_.SetScaleAndBounds(1.0f, screen_bounds); +} + +} // namespace headless |