Commit e1490a56 authored by thanhph's avatar thanhph Committed by Commit bot

Mash: Close app list widget when users click outside of the widget

Use PointerWatcherEventRouter/ui::PointerEvent to detect when a user clicks outside the visible app-list widget,
and close it. Make sure the app list is dismissed if the presenter is destroyed while it is visible.

BUG=611447

Review-Url: https://chromiumcodereview.appspot.com/2434573004
Cr-Commit-Position: refs/heads/master@{#426909}
parent 7f42fb35
......@@ -4,10 +4,13 @@
#include "chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.h"
#include "ui/app_list/presenter/app_list_presenter.h"
#include "ui/app_list/presenter/app_list_view_delegate_factory.h"
#include "ui/app_list/views/app_list_view.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/mus/pointer_watcher_event_router.h"
#include "ui/views/mus/window_manager_connection.h"
namespace {
......@@ -36,10 +39,15 @@ gfx::Point GetCenterOfDisplay(int64_t display_id, int minimum_height) {
} // namespace
AppListPresenterDelegateMus::AppListPresenterDelegateMus(
app_list::AppListPresenter* presenter,
app_list::AppListViewDelegateFactory* view_delegate_factory)
: view_delegate_factory_(view_delegate_factory) {}
: presenter_(presenter), view_delegate_factory_(view_delegate_factory) {}
AppListPresenterDelegateMus::~AppListPresenterDelegateMus() {}
AppListPresenterDelegateMus::~AppListPresenterDelegateMus() {
// Presenter is supposed to be dismissed when the delegate is destroyed. This
// means we don't have to worry about unregistering the PointerWatcher here.
DCHECK(!presenter_->GetTargetVisibility());
}
app_list::AppListViewDelegate* AppListPresenterDelegateMus::GetViewDelegate() {
return view_delegate_factory_->GetDelegate();
......@@ -66,24 +74,27 @@ void AppListPresenterDelegateMus::Init(app_list::AppListView* view,
GetCenterOfDisplay(display_id, GetMinimumBoundsHeightForAppList(view)));
// TODO(mfomitchev): Setup updating bounds on keyboard bounds change.
// TODO(mfomitchev): Setup dismissing on mouse/touch gesture anywhere outside
// the bounds of the app list.
// TODO(mfomitchev): Setup dismissing on maximize (touch-view) mode start/end.
// TODO(mfomitchev): Setup DnD.
// TODO(mfomitchev): UpdateAutoHideState for shelf
}
void AppListPresenterDelegateMus::OnShown(int64_t display_id) {
is_visible_ = true;
views::WindowManagerConnection::Get()
->pointer_watcher_event_router()
->AddPointerWatcher(this, false);
DCHECK(presenter_->GetTargetVisibility());
}
void AppListPresenterDelegateMus::OnDismissed() {
DCHECK(is_visible_);
is_visible_ = false;
views::WindowManagerConnection::Get()
->pointer_watcher_event_router()
->RemovePointerWatcher(this);
DCHECK(!presenter_->GetTargetVisibility());
}
void AppListPresenterDelegateMus::UpdateBounds() {
if (!view_ || !is_visible_)
if (!view_ || !presenter_->GetTargetVisibility())
return;
view_->UpdateBounds();
......@@ -95,3 +106,14 @@ gfx::Vector2d AppListPresenterDelegateMus::GetVisibilityAnimationOffset(
// shelf alignment. We should probably do that too.
return gfx::Vector2d(0, kAnimationOffset);
}
void AppListPresenterDelegateMus::OnPointerEventObserved(
const ui::PointerEvent& event,
const gfx::Point& location_in_screen,
views::Widget* target) {
// Dismiss app list on a mouse click or touch outside of the app list window.
if ((event.type() == ui::ET_TOUCH_PRESSED ||
event.type() == ui::ET_POINTER_DOWN) &&
(!target || (view_ && (target != view_->GetWidget()))))
presenter_->Dismiss();
}
......@@ -5,22 +5,25 @@
#ifndef CHROME_BROWSER_UI_ASH_APP_LIST_APP_LIST_PRESENTER_DELEGATE_MUS_H_
#define CHROME_BROWSER_UI_ASH_APP_LIST_APP_LIST_PRESENTER_DELEGATE_MUS_H_
#include "ui/app_list/presenter/app_list_presenter_delegate.h"
#include "base/macros.h"
#include "ui/app_list/presenter/app_list_presenter_delegate.h"
#include "ui/views/pointer_watcher.h"
namespace app_list {
class AppListPresenter;
class AppListView;
class AppListViewDelegateFactory;
}
} // namespace app_list
// Mus+ash implementation of AppListPresetnerDelegate.
// Responsible for laying out the app list UI as well as dismissing the app list
// on in response to certain events (e.g. on mouse/touch gesture outside of the
// app list bounds).
class AppListPresenterDelegateMus : public app_list::AppListPresenterDelegate {
class AppListPresenterDelegateMus : public app_list::AppListPresenterDelegate,
public views::PointerWatcher {
public:
explicit AppListPresenterDelegateMus(
AppListPresenterDelegateMus(
app_list::AppListPresenter* presenter,
app_list::AppListViewDelegateFactory* view_delegate_factory);
~AppListPresenterDelegateMus() override;
......@@ -36,8 +39,13 @@ class AppListPresenterDelegateMus : public app_list::AppListPresenterDelegate {
aura::Window* root_window) override;
private:
// Whether the app list is visible (or in the process of being shown).
bool is_visible_ = false;
// views::PointerWatcher:
void OnPointerEventObserved(const ui::PointerEvent& event,
const gfx::Point& location_in_screen,
views::Widget* target) override;
// Not owned. Pointer is guaranteed to be valid while this object is alive.
app_list::AppListPresenter* presenter_;
// Not owned. Pointer is guaranteed to be valid while this object is alive.
app_list::AppListViewDelegateFactory* view_delegate_factory_;
......
......@@ -60,7 +60,7 @@ class AppListPresenterDelegateFactoryMus
std::unique_ptr<app_list::AppListPresenterDelegate> GetDelegate(
app_list::AppListPresenter* presenter) override {
return base::MakeUnique<AppListPresenterDelegateMus>(
view_delegate_factory_.get());
presenter, view_delegate_factory_.get());
}
private:
......
......@@ -37,6 +37,7 @@ AppListPresenterImpl::AppListPresenterImpl(
}
AppListPresenterImpl::~AppListPresenterImpl() {
Dismiss();
presenter_delegate_.reset();
// Ensures app list view goes before the controller since pagination model
// lives in the controller and app list view would access it on destruction.
......
......@@ -53,7 +53,7 @@ class APP_LIST_PRESENTER_EXPORT AppListPresenterImpl
// AppListPresenter:
void Show(int64_t display_id) override;
void Dismiss() override;
void Dismiss() final;
void ToggleAppList(int64_t display_id) override;
bool IsVisible() const override;
bool GetTargetVisibility() const override;
......
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