Commit 5d860ae5 authored by Min Chen's avatar Min Chen Committed by Commit Bot

app_list: Don't hide auto-hide shelf if tap status area.

Tap inside the status area of auto-hide shelf with app list opened will
dismiss the app list and hide the shelf at the same time. This will
let the status area can't receive the gesture event to open the
corresponding tray bubble. This cl adds a lock for the auto-hide shelf
and uses it to lock the auto-hide shelf state if dismiss the app list
through tapping the status area of auto-hide shelf.

Bug: 902680
Change-Id: Ib946d57a25a664f3f0b80230d35a38a5c2cc1256
Reviewed-on: https://chromium-review.googlesource.com/c/1373012
Commit-Queue: Min Chen <minch@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#616036}
parent adbcb1d0
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "ash/shelf/shelf_layout_manager.h" #include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_widget.h" #include "ash/shelf/shelf_widget.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/system/status_area_widget.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_state.h" #include "ash/wm/window_state.h"
#include "base/command_line.h" #include "base/command_line.h"
...@@ -200,46 +201,53 @@ void AppListPresenterDelegateImpl::ProcessLocatedEvent( ...@@ -200,46 +201,53 @@ void AppListPresenterDelegateImpl::ProcessLocatedEvent(
return; return;
aura::Window* target = static_cast<aura::Window*>(event->target()); aura::Window* target = static_cast<aura::Window*>(event->target());
if (target) { if (!target)
// If the event happened on a menu, then the event should not close the app return;
// list. // If the event happened on a menu, then the event should not close the app
RootWindowController* root_controller = // list.
RootWindowController::ForWindow(target); RootWindowController* root_controller =
if (root_controller) { RootWindowController::ForWindow(target);
aura::Window* menu_container = if (root_controller) {
root_controller->GetContainer(kShellWindowId_MenuContainer); aura::Window* menu_container =
if (menu_container->Contains(target)) root_controller->GetContainer(kShellWindowId_MenuContainer);
return; if (menu_container->Contains(target))
aura::Window* keyboard_container = root_controller->GetContainer(
kShellWindowId_VirtualKeyboardContainer);
if (keyboard_container->Contains(target))
return;
}
// If the event happened on the app list button, it'll get handled by the
// button.
AppListButton* app_list_button =
Shelf::ForWindow(target)->shelf_widget()->GetAppListButton();
if (app_list_button && app_list_button->GetWidget() &&
target == app_list_button->GetWidget()->GetNativeWindow() &&
app_list_button->bounds().Contains(event->location())) {
return; return;
} aura::Window* keyboard_container =
root_controller->GetContainer(kShellWindowId_VirtualKeyboardContainer);
// If the event happened on the back button, it'll get handled by the if (keyboard_container->Contains(target))
// button.
BackButton* back_button =
Shelf::ForWindow(target)->shelf_widget()->GetBackButton();
if (back_button && back_button->GetWidget() &&
target == back_button->GetWidget()->GetNativeWindow() &&
back_button->bounds().Contains(event->location())) {
return; return;
} }
// If the event happened on the app list button, it'll get handled by the
// button.
Shelf* shelf = Shelf::ForWindow(target);
AppListButton* app_list_button = shelf->shelf_widget()->GetAppListButton();
if (app_list_button && app_list_button->GetWidget() &&
target == app_list_button->GetWidget()->GetNativeWindow() &&
app_list_button->bounds().Contains(event->location())) {
return;
}
// If the event happened on the back button, it'll get handled by the
// button.
BackButton* back_button = shelf->shelf_widget()->GetBackButton();
if (back_button && back_button->GetWidget() &&
target == back_button->GetWidget()->GetNativeWindow() &&
back_button->bounds().Contains(event->location())) {
return;
} }
aura::Window* window = view_->GetWidget()->GetNativeView()->parent(); aura::Window* window = view_->GetWidget()->GetNativeView()->parent();
if (!window->Contains(target) && !presenter_->CloseOpenedPage() && if (!window->Contains(target) && !presenter_->CloseOpenedPage() &&
!app_list::switches::ShouldNotDismissOnBlur() && !IsTabletMode()) { !app_list::switches::ShouldNotDismissOnBlur() && !IsTabletMode()) {
// Dismiss the app list but not the auto-hide shelf if the event happened in
// the status area. Since tap the tray in the status area should open the
// corresponding tray bubble.
aura::Window* status_window =
shelf->shelf_widget()->status_area_widget()->GetNativeWindow();
base::Optional<Shelf::ScopedAutoHideLock> auto_hide_lock;
if (status_window && status_window->Contains(target))
auto_hide_lock.emplace(shelf);
presenter_->Dismiss(event->time_stamp()); presenter_->Dismiss(event->time_stamp());
} }
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "ash/shelf/shelf_view.h" #include "ash/shelf/shelf_view.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/shell_test_api.h" #include "ash/shell_test_api.h"
#include "ash/system/unified/unified_system_tray.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "ash/wallpaper/wallpaper_controller_test_api.h" #include "ash/wallpaper/wallpaper_controller_test_api.h"
#include "ash/wm/mru_window_tracker.h" #include "ash/wm/mru_window_tracker.h"
...@@ -1107,6 +1108,33 @@ TEST_F(AppListPresenterDelegateTest, ShowInInvalidDisplay) { ...@@ -1107,6 +1108,33 @@ TEST_F(AppListPresenterDelegateTest, ShowInInvalidDisplay) {
GetAppListTestHelper()->CheckState(app_list::AppListViewState::CLOSED); GetAppListTestHelper()->CheckState(app_list::AppListViewState::CLOSED);
} }
// Tests that tap the status area of auto-hide shelf with app list opened should
// open the corresponding tray bubble but dismiss the app list.
TEST_F(AppListPresenterDelegateTest,
TapStatusAreaOfAutoHideShelfWithAppListOpened) {
Shelf* shelf = GetPrimaryShelf();
shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
// Create a normal unmaximized window; the shelf should be hidden.
std::unique_ptr<views::Widget> window = CreateTestWidget();
window->SetBounds(gfx::Rect(0, 0, 100, 100));
GetAppListTestHelper()->CheckVisibility(false);
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
GetAppListTestHelper()->CheckVisibility(true);
EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
// Tap the system tray should open system tray bubble and keep shelf visible.
ui::test::EventGenerator* generator = GetEventGenerator();
generator->GestureTapAt(
GetPrimaryUnifiedSystemTray()->GetBoundsInScreen().CenterPoint());
EXPECT_TRUE(GetPrimaryUnifiedSystemTray()->IsBubbleShown());
GetAppListTestHelper()->CheckVisibility(false);
EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
}
// Test a variety of behaviors for home launcher (app list in tablet mode). // Test a variety of behaviors for home launcher (app list in tablet mode).
class AppListPresenterDelegateHomeLauncherTest class AppListPresenterDelegateHomeLauncherTest
: public AppListPresenterDelegateTest { : public AppListPresenterDelegateTest {
......
...@@ -44,6 +44,22 @@ class TrayBackgroundView; ...@@ -44,6 +44,22 @@ class TrayBackgroundView;
// root window controller. // root window controller.
class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver { class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
public: public:
// Used to maintain a lock for the auto-hide shelf. If lock, then we should
// not update the state of the auto-hide shelf.
class ScopedAutoHideLock {
public:
explicit ScopedAutoHideLock(Shelf* shelf) : shelf_(shelf) {
++shelf_->auto_hide_lock_;
}
~ScopedAutoHideLock() {
--shelf_->auto_hide_lock_;
DCHECK_GE(shelf_->auto_hide_lock_, 0);
}
private:
Shelf* shelf_;
};
Shelf(); Shelf();
~Shelf() override; ~Shelf() override;
...@@ -163,6 +179,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver { ...@@ -163,6 +179,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
bool is_tablet_mode_animation_running() const { bool is_tablet_mode_animation_running() const {
return is_tablet_mode_animation_running_; return is_tablet_mode_animation_running_;
} }
int auto_hide_lock() const { return auto_hide_lock_; }
protected: protected:
// ShelfLayoutManagerObserver: // ShelfLayoutManagerObserver:
...@@ -205,6 +222,10 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver { ...@@ -205,6 +222,10 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
// the animation for AppListButton. // the animation for AppListButton.
bool is_tablet_mode_animation_running_ = false; bool is_tablet_mode_animation_running_ = false;
// Used by ScopedAutoHideLock to maintain the state of the lock for auto-hide
// shelf.
int auto_hide_lock_ = 0;
DISALLOW_COPY_AND_ASSIGN(Shelf); DISALLOW_COPY_AND_ASSIGN(Shelf);
}; };
......
...@@ -1063,6 +1063,10 @@ ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState( ...@@ -1063,6 +1063,10 @@ ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
if (visibility_state != SHELF_AUTO_HIDE) if (visibility_state != SHELF_AUTO_HIDE)
return SHELF_AUTO_HIDE_HIDDEN; return SHELF_AUTO_HIDE_HIDDEN;
// Don't update the auto hide state if it is locked.
if (shelf_->auto_hide_lock())
return state_.auto_hide_state;
if (shelf_widget_->IsShowingAppList() && !IsHomeLauncherEnabledInTabletMode()) if (shelf_widget_->IsShowingAppList() && !IsHomeLauncherEnabledInTabletMode())
return SHELF_AUTO_HIDE_SHOWN; return SHELF_AUTO_HIDE_SHOWN;
......
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