blob: 1f29c2c8b284757da7083c38de391ec84bd65fe8 [file] [log] [blame]
// Copyright (c) 2012 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 "ash/touch/touch_observer_hud.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/root_window_controller.h"
#include "ash/root_window_settings.h"
#include "ash/shell.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/widget/widget.h"
namespace ash {
TouchObserverHud::TouchObserverHud(aura::Window* initial_root,
const std::string& widget_name)
: display_id_(GetRootWindowSettings(initial_root)->display_id),
root_window_(initial_root),
widget_(new views::Widget()) {
const display::Display& display =
Shell::Get()->display_manager()->GetDisplayForId(display_id_);
views::View* content = new views::View;
const gfx::Size& display_size = display.size();
content->SetSize(display_size);
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
params.accept_events = false;
params.bounds = display.bounds();
params.parent =
Shell::GetContainer(root_window_, kShellWindowId_OverlayContainer);
params.name = widget_name;
widget_->Init(params);
widget_->SetContentsView(content);
widget_->StackAtTop();
widget_->Show();
widget_->AddObserver(this);
// Observe changes in display size and mode to update touch HUD.
display::Screen::GetScreen()->AddObserver(this);
Shell::Get()->display_configurator()->AddObserver(this);
Shell::Get()->window_tree_host_manager()->AddObserver(this);
root_window_->AddPreTargetHandler(this);
}
TouchObserverHud::~TouchObserverHud() {
Shell::Get()->window_tree_host_manager()->RemoveObserver(this);
Shell::Get()->display_configurator()->RemoveObserver(this);
display::Screen::GetScreen()->RemoveObserver(this);
widget_->RemoveObserver(this);
}
void TouchObserverHud::Remove() {
root_window_->RemovePreTargetHandler(this);
RootWindowController* controller =
RootWindowController::ForWindow(root_window_);
UnsetHudForRootWindowController(controller);
widget_->CloseNow();
}
void TouchObserverHud::OnWidgetDestroying(views::Widget* widget) {
DCHECK_EQ(widget, widget_);
delete this;
}
void TouchObserverHud::OnDisplayRemoved(const display::Display& old_display) {
if (old_display.id() != display_id_)
return;
widget_->CloseNow();
}
void TouchObserverHud::OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) {
if (display.id() != display_id_ || !(metrics & DISPLAY_METRIC_BOUNDS))
return;
widget_->SetSize(display.size());
}
void TouchObserverHud::OnDisplayModeChanged(
const display::DisplayConfigurator::DisplayStateList& outputs) {
// Clear touch HUD for any change in display mode (single, dual extended, dual
// mirrored, ...).
Clear();
}
void TouchObserverHud::OnDisplaysInitialized() {
OnDisplayConfigurationChanged();
}
void TouchObserverHud::OnDisplayConfigurationChanging() {
if (!root_window_)
return;
root_window_->RemovePreTargetHandler(this);
RootWindowController* controller =
RootWindowController::ForWindow(root_window_);
UnsetHudForRootWindowController(controller);
views::Widget::ReparentNativeView(
widget_->GetNativeView(),
Shell::GetContainer(root_window_,
kShellWindowId_UnparentedControlContainer));
root_window_ = NULL;
}
void TouchObserverHud::OnDisplayConfigurationChanged() {
if (root_window_)
return;
root_window_ = Shell::GetRootWindowForDisplayId(display_id_);
views::Widget::ReparentNativeView(
widget_->GetNativeView(),
Shell::GetContainer(root_window_, kShellWindowId_OverlayContainer));
RootWindowController* controller =
RootWindowController::ForWindow(root_window_);
SetHudForRootWindowController(controller);
root_window_->AddPreTargetHandler(this);
}
} // namespace ash