blob: 8618d1bbbd12af3440d43ea3ebdb0912f9c94705 [file] [log] [blame]
// 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.
// This has to be before any other includes, else default is picked up.
// See base/logging for details on this.
#define NOTIMPLEMENTED_POLICY 5
#include "ui/views/mus/screen_mus.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/views/mus/screen_mus_delegate.h"
#include "ui/views/mus/window_manager_frame_values.h"
namespace mojo {
template <>
struct TypeConverter<views::WindowManagerFrameValues,
ui::mojom::FrameDecorationValuesPtr> {
static views::WindowManagerFrameValues Convert(
const ui::mojom::FrameDecorationValuesPtr& input) {
views::WindowManagerFrameValues result;
result.normal_insets = input->normal_client_area_insets;
result.maximized_insets = input->maximized_client_area_insets;
result.max_title_bar_button_width = input->max_title_bar_button_width;
return result;
}
};
} // namespace mojo
namespace views {
using Type = display::DisplayList::Type;
ScreenMus::ScreenMus(ScreenMusDelegate* delegate)
: delegate_(delegate), display_manager_observer_binding_(this) {
DCHECK(delegate);
display::Screen::SetScreenInstance(this);
}
ScreenMus::~ScreenMus() {
DCHECK_EQ(this, display::Screen::GetScreen());
display::Screen::SetScreenInstance(nullptr);
}
void ScreenMus::Init(service_manager::Connector* connector) {
connector->BindInterface(ui::mojom::kServiceName, &display_manager_);
display_manager_->AddObserver(
display_manager_observer_binding_.CreateInterfacePtrAndBind());
// We need the set of displays before we can continue. Wait for it.
//
// TODO(rockot): Do something better here. This should not have to block tasks
// from running on the calling thread. http://crbug.com/594852.
bool success = display_manager_observer_binding_.WaitForIncomingMethodCall();
// The WaitForIncomingMethodCall() should have supplied the set of Displays,
// unless mus is going down, in which case encountered_error() is true, or the
// call to WaitForIncomingMethodCall() failed.
if (display_list().displays().empty()) {
DCHECK(display_manager_.encountered_error() || !success);
// In this case we install a default display and assume the process is
// going to exit shortly so that the real value doesn't matter.
display_list().AddDisplay(
display::Display(0xFFFFFFFF, gfx::Rect(0, 0, 801, 802)), Type::PRIMARY);
}
}
display::Display ScreenMus::GetDisplayNearestWindow(
gfx::NativeWindow window) const {
aura::WindowTreeHostMus* window_tree_host_mus =
aura::WindowTreeHostMus::ForWindow(window);
if (!window_tree_host_mus)
return GetPrimaryDisplay();
return window_tree_host_mus->GetDisplay();
}
gfx::Point ScreenMus::GetCursorScreenPoint() {
return aura::Env::GetInstance()->last_mouse_location();
}
bool ScreenMus::IsWindowUnderCursor(gfx::NativeWindow window) {
return window && window->IsVisible() &&
window->GetBoundsInScreen().Contains(GetCursorScreenPoint());
}
aura::Window* ScreenMus::GetWindowAtScreenPoint(const gfx::Point& point) {
return delegate_->GetWindowAtScreenPoint(point);
}
void ScreenMus::OnDisplays(std::vector<ui::mojom::WsDisplayPtr> ws_displays,
int64_t primary_display_id,
int64_t internal_display_id) {
// This should only be called once when ScreenMus is added as an observer.
DCHECK(display_list().displays().empty());
for (size_t i = 0; i < ws_displays.size(); ++i) {
const display::Display& display = ws_displays[i]->display;
const bool is_primary = display.id() == primary_display_id;
display_list().AddDisplay(display,
is_primary ? Type::PRIMARY : Type::NOT_PRIMARY);
if (is_primary) {
// TODO(sky): Make WindowManagerFrameValues per display.
WindowManagerFrameValues frame_values =
ws_displays[i]
->frame_decoration_values.To<WindowManagerFrameValues>();
WindowManagerFrameValues::SetInstance(frame_values);
}
}
DCHECK(display_list().GetPrimaryDisplayIterator() !=
display_list().displays().end());
if (internal_display_id != display::kInvalidDisplayId)
display::Display::SetInternalDisplayId(internal_display_id);
DCHECK(!display_list().displays().empty());
}
void ScreenMus::OnDisplaysChanged(
std::vector<ui::mojom::WsDisplayPtr> ws_displays) {
for (size_t i = 0; i < ws_displays.size(); ++i) {
const display::Display& display = ws_displays[i]->display;
const bool is_primary =
display.id() == display_list().GetPrimaryDisplayIterator()->id();
ProcessDisplayChanged(display, is_primary);
if (is_primary) {
WindowManagerFrameValues frame_values =
ws_displays[i]
->frame_decoration_values.To<WindowManagerFrameValues>();
WindowManagerFrameValues::SetInstance(frame_values);
delegate_->OnWindowManagerFrameValuesChanged();
}
}
}
void ScreenMus::OnDisplayRemoved(int64_t display_id) {
display_list().RemoveDisplay(display_id);
}
void ScreenMus::OnPrimaryDisplayChanged(int64_t primary_display_id) {
// TODO(kylechar): DisplayList would need to change to handle having no
// primary display.
if (primary_display_id == display::kInvalidDisplayId)
return;
ProcessDisplayChanged(*display_list().FindDisplayById(primary_display_id),
true);
}
} // namespace views