Commit e319550a authored by James Cook's avatar James Cook Committed by Commit Bot

cros: Fix touch HUD application to support multiple displays

Create one touch hud views::Widget per display and open/close new
widgets as displays are added and removed.

Bug: 840380
Test: run chrome --show-taps-app and add/remove displays
Change-Id: I21c87b35ec520bd1501f0cbf02c073d030c7ff64
Reviewed-on: https://chromium-review.googlesource.com/1058591
Commit-Queue: James Cook <jamescook@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558731}
parent f0425a24
...@@ -7,5 +7,6 @@ include_rules = [ ...@@ -7,5 +7,6 @@ include_rules = [
"+services/service_manager/public", "+services/service_manager/public",
"+services/ui/public", "+services/ui/public",
"+ui/aura", "+ui/aura",
"+ui/display",
"+ui/views", "+ui/views",
] ]
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/cpp/property_type_converters.h"
#include "services/ui/public/interfaces/window_manager_constants.mojom.h" #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
#include "ui/aura/mus/property_converter.h" #include "ui/aura/mus/property_converter.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/mus/aura_init.h" #include "ui/views/mus/aura_init.h"
#include "ui/views/mus/mus_client.h" #include "ui/views/mus/mus_client.h"
#include "ui/views/mus/pointer_watcher_event_router.h" #include "ui/views/mus/pointer_watcher_event_router.h"
...@@ -23,6 +25,7 @@ ...@@ -23,6 +25,7 @@
#include "ui/views/widget/widget_delegate.h" #include "ui/views/widget/widget_delegate.h"
namespace touch_hud { namespace touch_hud {
namespace {
// TouchHudUI handles events on the widget of the touch-hud app. After // TouchHudUI handles events on the widget of the touch-hud app. After
// receiving touch events from PointerWatcher, it calls ash::TouchHudRenderer to // receiving touch events from PointerWatcher, it calls ash::TouchHudRenderer to
...@@ -31,7 +34,8 @@ class TouchHudUI : public views::WidgetDelegateView, ...@@ -31,7 +34,8 @@ class TouchHudUI : public views::WidgetDelegateView,
public views::PointerWatcher { public views::PointerWatcher {
public: public:
explicit TouchHudUI(views::Widget* widget) explicit TouchHudUI(views::Widget* widget)
: touch_hud_renderer_(new ash::TouchHudRenderer(widget)) { : touch_hud_renderer_(std::make_unique<ash::TouchHudRenderer>(widget)) {
// Watches moves so the user can drag around a touch point.
views::MusClient::Get()->pointer_watcher_event_router()->AddPointerWatcher( views::MusClient::Get()->pointer_watcher_event_router()->AddPointerWatcher(
this, true /* want_moves */); this, true /* want_moves */);
} }
...@@ -52,21 +56,31 @@ class TouchHudUI : public views::WidgetDelegateView, ...@@ -52,21 +56,31 @@ class TouchHudUI : public views::WidgetDelegateView,
void OnPointerEventObserved(const ui::PointerEvent& event, void OnPointerEventObserved(const ui::PointerEvent& event,
const gfx::Point& location_in_screen, const gfx::Point& location_in_screen,
gfx::NativeView target) override { gfx::NativeView target) override {
if (event.IsTouchPointerEvent()) if (!event.IsTouchPointerEvent())
touch_hud_renderer_->HandleTouchEvent(event); return;
// Ignore taps on other displays.
if (!GetWidget()->GetWindowBoundsInScreen().Contains(location_in_screen))
return;
touch_hud_renderer_->HandleTouchEvent(event);
} }
// TODO(jamescook): Don't leak this. std::unique_ptr<ash::TouchHudRenderer> touch_hud_renderer_;
ash::TouchHudRenderer* touch_hud_renderer_;
DISALLOW_COPY_AND_ASSIGN(TouchHudUI); DISALLOW_COPY_AND_ASSIGN(TouchHudUI);
}; };
} // namespace
TouchHudApplication::TouchHudApplication() : binding_(this) { TouchHudApplication::TouchHudApplication() : binding_(this) {
registry_.AddInterface<mash::mojom::Launchable>(base::BindRepeating( registry_.AddInterface<mash::mojom::Launchable>(base::BindRepeating(
&TouchHudApplication::Create, base::Unretained(this))); &TouchHudApplication::Create, base::Unretained(this)));
} }
TouchHudApplication::~TouchHudApplication() = default;
TouchHudApplication::~TouchHudApplication() {
display::Screen::GetScreen()->RemoveObserver(this);
}
void TouchHudApplication::OnStart() { void TouchHudApplication::OnStart() {
const bool register_path_provider = running_standalone_; const bool register_path_provider = running_standalone_;
...@@ -78,6 +92,7 @@ void TouchHudApplication::OnStart() { ...@@ -78,6 +92,7 @@ void TouchHudApplication::OnStart() {
context()->QuitNow(); context()->QuitNow();
return; return;
} }
display::Screen::GetScreen()->AddObserver(this);
Launch(mash::mojom::kWindow, mash::mojom::LaunchMode::DEFAULT); Launch(mash::mojom::kWindow, mash::mojom::LaunchMode::DEFAULT);
} }
...@@ -89,25 +104,43 @@ void TouchHudApplication::OnBindInterface( ...@@ -89,25 +104,43 @@ void TouchHudApplication::OnBindInterface(
} }
void TouchHudApplication::Launch(uint32_t what, mash::mojom::LaunchMode how) { void TouchHudApplication::Launch(uint32_t what, mash::mojom::LaunchMode how) {
if (!widget_) { for (const display::Display& display :
widget_ = new views::Widget; display::Screen::GetScreen()->GetAllDisplays()) {
views::Widget::InitParams params( CreateWidgetForDisplay(display.id());
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.delegate = new TouchHudUI(widget_);
params.mus_properties[ui::mojom::WindowManager::kContainerId_InitProperty] =
mojo::ConvertTo<std::vector<uint8_t>>(
static_cast<int32_t>(ash::kShellWindowId_OverlayContainer));
params.show_state = ui::SHOW_STATE_FULLSCREEN;
widget_->Init(params);
widget_->Show();
} else {
widget_->Activate();
} }
} }
void TouchHudApplication::OnDisplayAdded(const display::Display& new_display) {
CreateWidgetForDisplay(new_display.id());
}
void TouchHudApplication::OnDisplayRemoved(
const display::Display& old_display) {
// Deletes the widget.
display_id_to_widget_.erase(old_display.id());
}
void TouchHudApplication::CreateWidgetForDisplay(int64_t display_id) {
std::unique_ptr<views::Widget> widget = std::make_unique<views::Widget>();
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
params.accept_events = false;
params.delegate = new TouchHudUI(widget.get());
params.mus_properties[ui::mojom::WindowManager::kContainerId_InitProperty] =
mojo::ConvertTo<std::vector<uint8_t>>(
static_cast<int32_t>(ash::kShellWindowId_OverlayContainer));
params.mus_properties[ui::mojom::WindowManager::kDisplayId_InitProperty] =
mojo::ConvertTo<std::vector<uint8_t>>(display_id);
params.show_state = ui::SHOW_STATE_FULLSCREEN;
params.name = "TouchHud";
widget->Init(params);
widget->Show();
display_id_to_widget_[display_id] = std::move(widget);
}
void TouchHudApplication::Create(mash::mojom::LaunchableRequest request) { void TouchHudApplication::Create(mash::mojom::LaunchableRequest request) {
binding_.Close(); binding_.Close();
binding_.Bind(std::move(request)); binding_.Bind(std::move(request));
......
...@@ -5,11 +5,17 @@ ...@@ -5,11 +5,17 @@
#ifndef ASH_COMPONENTS_TOUCH_HUD_TOUCH_HUD_APPLICATION_H_ #ifndef ASH_COMPONENTS_TOUCH_HUD_TOUCH_HUD_APPLICATION_H_
#define ASH_COMPONENTS_TOUCH_HUD_TOUCH_HUD_APPLICATION_H_ #define ASH_COMPONENTS_TOUCH_HUD_TOUCH_HUD_APPLICATION_H_
#include <stdint.h>
#include <map>
#include <memory>
#include "base/macros.h" #include "base/macros.h"
#include "mash/public/mojom/launchable.mojom.h" #include "mash/public/mojom/launchable.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service.h"
#include "ui/display/display_observer.h"
namespace views { namespace views {
class AuraInit; class AuraInit;
...@@ -18,8 +24,11 @@ class Widget; ...@@ -18,8 +24,11 @@ class Widget;
namespace touch_hud { namespace touch_hud {
// Application that paints touch tap points as circles. Creates a fullscreen
// transparent widget on each display to draw the taps.
class TouchHudApplication : public service_manager::Service, class TouchHudApplication : public service_manager::Service,
public mash::mojom::Launchable { public mash::mojom::Launchable,
public display::DisplayObserver {
public: public:
TouchHudApplication(); TouchHudApplication();
~TouchHudApplication() override; ~TouchHudApplication() override;
...@@ -36,11 +45,20 @@ class TouchHudApplication : public service_manager::Service, ...@@ -36,11 +45,20 @@ class TouchHudApplication : public service_manager::Service,
// mojom::Launchable: // mojom::Launchable:
void Launch(uint32_t what, mash::mojom::LaunchMode how) override; void Launch(uint32_t what, mash::mojom::LaunchMode how) override;
// display::DisplayObserver:
void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplayRemoved(const display::Display& old_display) override;
// Creates the touch HUD widget for a display.
void CreateWidgetForDisplay(int64_t display_id);
void Create(mash::mojom::LaunchableRequest request); void Create(mash::mojom::LaunchableRequest request);
service_manager::BinderRegistry registry_; service_manager::BinderRegistry registry_;
mojo::Binding<mash::mojom::Launchable> binding_; mojo::Binding<mash::mojom::Launchable> binding_;
views::Widget* widget_ = nullptr;
// Maps display::Display::id() to the touch HUD widget for that display.
std::map<int64_t, std::unique_ptr<views::Widget>> display_id_to_widget_;
std::unique_ptr<views::AuraInit> aura_init_; std::unique_ptr<views::AuraInit> aura_init_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment