Commit f05a6730 authored by msw's avatar msw Committed by Commit bot

Fix shelf auto-hide calculation for app-list visibility.

AppListButton tracks per-display [target] visibility.
(sets a new flag on Shown/Dismissed callbacks)

Check widget/button state, not global shell state.
Ignore dismissed app-list windows that are animating closed.

Fix a ShelfLayoutManager test to actually catch this.

BUG=654661
TEST=Shelf stays visible when the app-list is hidden.
R=jamescook@chromium.org

Review-Url: https://codereview.chromium.org/2534953006
Cr-Commit-Position: refs/heads/master@{#435554}
parent 20cd03e4
......@@ -164,13 +164,9 @@ void AppListPresenterDelegate::OnDismissed() {
is_visible_ = false;
// App list needs to know the new shelf layout in order to calculate its
// UI layout when AppListView visibility changes.
// Update applist button status when app list visibility is changed.
WmShelf* shelf = WmShelf::ForWindow(
WmLookup::Get()->GetWindowForWidget(view_->GetWidget()));
shelf->UpdateAutoHideState();
// Update applist button status when app list visibility is changed.
shelf->shelf_widget()->GetAppListButton()->OnAppListDismissed();
}
......
......@@ -34,6 +34,7 @@ AppListButton::AppListButton(InkDropButtonListener* listener,
ShelfView* shelf_view,
WmShelf* wm_shelf)
: views::ImageButton(nullptr),
is_showing_app_list_(false),
draw_background_as_active_(false),
background_alpha_(0),
listener_(listener),
......@@ -62,6 +63,8 @@ void AppListButton::OnAppListShown() {
AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr);
else
SchedulePaint();
is_showing_app_list_ = true;
wm_shelf_->UpdateAutoHideState();
}
void AppListButton::OnAppListDismissed() {
......@@ -69,6 +72,8 @@ void AppListButton::OnAppListDismissed() {
AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr);
else
SchedulePaint();
is_showing_app_list_ = false;
wm_shelf_->UpdateAutoHideState();
}
void AppListButton::SetBackgroundAlpha(int alpha) {
......
......@@ -25,7 +25,9 @@ class ASH_EXPORT AppListButton : public views::ImageButton {
void OnAppListShown();
void OnAppListDismissed();
bool draw_background_as_active() { return draw_background_as_active_; }
bool is_showing_app_list() const { return is_showing_app_list_; }
bool draw_background_as_active() const { return draw_background_as_active_; }
// Sets alpha value of the background and schedules a paint.
void SetBackgroundAlpha(int alpha);
......@@ -63,6 +65,10 @@ class ASH_EXPORT AppListButton : public views::ImageButton {
// ink drops.
gfx::Point GetCenterPoint() const;
// True if the app list is currently showing for this display.
// This is useful because other IsApplistVisible functions aren't per-display.
bool is_showing_app_list_;
// True if the background should render as active, regardless of the state of
// the application list.
bool draw_background_as_active_;
......
......@@ -71,6 +71,13 @@ ui::Layer* GetLayer(views::Widget* widget) {
return widget->GetNativeView()->layer();
}
// Returns true if the window is in the app list window container.
bool IsAppListWindow(WmWindow* window) {
return window->GetParent() &&
window->GetParent()->GetShellWindowId() ==
kShellWindowId_AppListContainer;
}
} // namespace
// ShelfLayoutManager::UpdateShelfObserver -------------------------------------
......@@ -830,18 +837,8 @@ ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
if (visibility_state != SHELF_AUTO_HIDE || !wm_shelf_->IsShelfInitialized())
return SHELF_AUTO_HIDE_HIDDEN;
const int64_t shelf_display_id = WmLookup::Get()
->GetWindowForWidget(shelf_widget_)
->GetDisplayNearestWindow()
.id();
// Unhide the shelf only on the active screen when the AppList is shown
// (crbug.com/312445).
if (WmShell::Get()->GetAppListTargetVisibility()) {
WmWindow* window = WmShell::Get()->GetActiveWindow();
if (window && window->GetDisplayNearestWindow().id() == shelf_display_id)
return SHELF_AUTO_HIDE_SHOWN;
}
if (shelf_widget_->IsShowingAppList())
return SHELF_AUTO_HIDE_SHOWN;
if (shelf_widget_->status_area_widget() &&
shelf_widget_->status_area_widget()->ShouldShowShelf())
......@@ -858,13 +855,17 @@ ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
shelf_widget_->status_area_widget()->IsActive()))
return SHELF_AUTO_HIDE_SHOWN;
const int64_t shelf_display_id = WmLookup::Get()
->GetWindowForWidget(shelf_widget_)
->GetDisplayNearestWindow()
.id();
const std::vector<WmWindow*> windows =
WmShell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal();
// Process the window list and check if there are any visible windows.
// Ignore app list windows that may be animating to hide after dismissal.
bool visible_window = false;
for (size_t i = 0; i < windows.size(); ++i) {
if (windows[i] && windows[i]->IsVisible() &&
if (windows[i] && windows[i]->IsVisible() && !IsAppListWindow(windows[i]) &&
!windows[i]->GetWindowState()->IsMinimized() &&
windows[i]->GetDisplayNearestWindow().id() == shelf_display_id) {
visible_window = true;
......
......@@ -7,6 +7,7 @@
#include "ash/common/focus_cycler.h"
#include "ash/common/material_design/material_design_controller.h"
#include "ash/common/session/session_state_delegate.h"
#include "ash/common/shelf/app_list_button.h"
#include "ash/common/shelf/shelf_background_animator_observer.h"
#include "ash/common/shelf/shelf_constants.h"
#include "ash/common/shelf/shelf_delegate.h"
......@@ -433,6 +434,10 @@ void ShelfWidget::SetShelfVisibility(bool visible) {
shelf_view_->SetVisible(visible);
}
bool ShelfWidget::IsShowingAppList() const {
return GetAppListButton() && GetAppListButton()->is_showing_app_list();
}
bool ShelfWidget::IsShowingContextMenu() const {
return shelf_view_ && shelf_view_->IsShowingMenu();
}
......@@ -496,7 +501,7 @@ gfx::Rect ShelfWidget::GetScreenBoundsOfItemIconForWindow(WmWindow* window) {
}
AppListButton* ShelfWidget::GetAppListButton() const {
return shelf_view_->GetAppListButton();
return shelf_view_ ? shelf_view_->GetAppListButton() : nullptr;
}
app_list::ApplicationDragAndDropHost*
......
......@@ -68,8 +68,8 @@ class ASH_EXPORT ShelfWidget : public views::Widget,
void SetShelfVisibility(bool visible);
bool IsShelfVisible() const;
bool IsShowingAppList() const;
bool IsShowingContextMenu() const;
bool IsShowingOverflowBubble() const;
// Sets the focus cycler. Also adds the shelf to the cycle.
......
......@@ -1132,7 +1132,7 @@ TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) {
layout_manager->LayoutShelf();
shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
// Create a normal unmaximized windowm shelf should be visible.
// Create a normal unmaximized window, shelf should be visible.
aura::Window* window = CreateTestWindow();
window->SetBounds(gfx::Rect(0, 0, 100, 100));
window->Show();
......@@ -1160,15 +1160,9 @@ TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) {
layout_manager->LayoutShelf();
shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
// Create a window and show it in maximized state.
aura::Window* window = CreateTestWindow();
window->SetBounds(gfx::Rect(0, 0, 100, 100));
window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
window->Show();
wm::ActivateWindow(window);
EXPECT_FALSE(shell->GetAppListTargetVisibility());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
// Show app list.
shell->ShowAppList();
......@@ -1183,6 +1177,7 @@ TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) {
shell->DismissAppList();
EXPECT_FALSE(shell->GetAppListTargetVisibility());
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
}
// Makes sure that when we have dual displays, with one or both shelves are set
......
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