Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Unified Diff: ash/shelf/shelf_layout_manager.cc

Issue 22638013: Prevent a user from hiding the shelf via a gesture when there are no visible windows part 2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ash/shelf/shelf_layout_manager.cc
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index 8210b5beaeabaedc3b0b32ad64099a165e115b12..a507da648a839e58de1b06987e4e344ea9226e16 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -36,6 +36,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "ui/aura/client/activation_client.h"
+#include "ui/aura/client/cursor_client.h"
#include "ui/aura/root_window.h"
#include "ui/base/events/event.h"
#include "ui/base/events/event_handler.h"
@@ -196,7 +197,7 @@ class ShelfLayoutManager::UpdateShelfObserver
ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf)
: root_window_(shelf->GetNativeView()->GetRootWindow()),
- in_layout_(false),
+ updating_bounds_(false),
auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_NEVER),
alignment_(SHELF_ALIGNMENT_BOTTOM),
shelf_(shelf),
@@ -271,34 +272,20 @@ gfx::Rect ShelfLayoutManager::GetIdealBounds() {
}
void ShelfLayoutManager::LayoutShelf() {
- base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
- StopAnimating();
TargetBounds target_bounds;
CalculateTargetBounds(state_, &target_bounds);
- GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
- shelf_->SetWidgetBounds(
- ScreenAsh::ConvertRectToScreen(
- shelf_->GetNativeView()->parent(),
- target_bounds.shelf_bounds_in_root));
- if (shelf_->launcher())
+ UpdateBoundsAndOpacity(target_bounds, false, NULL);
+
+ if (shelf_->launcher()) {
+ // This is not part of UpdateBoundsAndOpacity() because
+ // SetLauncherViewBounds() sets the bounds immediately and does not animate.
+ // The height of the LauncherView for a horizontal shelf and the width of
+ // the LauncherView for a vertical shelf are set when |shelf_|'s bounds
+ // are changed via UpdateBoundsAndOpacity(). This sets the origin and the
+ // dimension in the other direction.
shelf_->launcher()->SetLauncherViewBounds(
target_bounds.launcher_bounds_in_shelf);
- GetLayer(shelf_->status_area_widget())->SetOpacity(
- target_bounds.status_opacity);
- // TODO(harrym): Once status area widget is a child view of shelf
- // this can be simplified.
- gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
- status_bounds.set_x(status_bounds.x() +
- target_bounds.shelf_bounds_in_root.x());
- status_bounds.set_y(status_bounds.y() +
- target_bounds.shelf_bounds_in_root.y());
- shelf_->status_area_widget()->SetBounds(
- ScreenAsh::ConvertRectToScreen(
- shelf_->status_area_widget()->GetNativeView()->parent(),
- status_bounds));
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- root_window_, target_bounds.work_area_insets);
- UpdateHitTestBounds();
+ }
}
ShelfVisibilityState ShelfLayoutManager::CalculateShelfVisibility() {
@@ -480,17 +467,12 @@ void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) {
else
UpdateVisibilityState();
gesture_drag_status_ = GESTURE_DRAG_NONE;
- LayoutShelf();
}
void ShelfLayoutManager::CancelGestureDrag() {
- gesture_drag_status_ = GESTURE_DRAG_NONE;
- ui::ScopedLayerAnimationSettings
- launcher_settings(GetLayer(shelf_)->GetAnimator()),
- status_settings(GetLayer(shelf_->status_area_widget())->GetAnimator());
- LayoutShelf();
+ gesture_drag_status_ = GESTURE_DRAG_CANCEL_IN_PROGRESS;
UpdateVisibilityState();
- UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
+ gesture_drag_status_ = GESTURE_DRAG_NONE;
}
////////////////////////////////////////////////////////////////////////////////
@@ -518,7 +500,7 @@ void ShelfLayoutManager::SetChildBounds(aura::Window* child,
SetChildBoundsDirect(child, requested_bounds);
// We may contain other widgets (such as frame maximize bubble) but they don't
// effect the layout in anyway.
- if (!in_layout_ &&
+ if (!updating_bounds_ &&
((shelf_->GetNativeView() == child) ||
(shelf_->status_area_widget()->GetNativeView() == child))) {
LayoutShelf();
@@ -575,7 +557,13 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
state.window_state = workspace_controller_ ?
workspace_controller_->GetWindowState() : WORKSPACE_WINDOW_STATE_DEFAULT;
- if (state_.Equals(state))
+ // Force an update because gesture drags affect the shelf bounds and we
+ // should animate back to the normal bounds at the end of a gesture.
+ bool force_update =
+ (gesture_drag_status_ == GESTURE_DRAG_CANCEL_IN_PROGRESS ||
+ gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS);
+
+ if (!force_update && state_.Equals(state))
return; // Nothing changed.
FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
@@ -594,26 +582,6 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
State old_state = state_;
state_ = state;
- TargetBounds target_bounds;
- CalculateTargetBounds(state_, &target_bounds);
-
- ui::ScopedLayerAnimationSettings launcher_animation_setter(
- GetLayer(shelf_)->GetAnimator());
- launcher_animation_setter.SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS));
- launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
- launcher_animation_setter.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- GetLayer(shelf_)->SetBounds(
- target_bounds.shelf_bounds_in_root);
- GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
- ui::ScopedLayerAnimationSettings status_animation_setter(
- GetLayer(shelf_->status_area_widget())->GetAnimator());
- status_animation_setter.SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS));
- status_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
- status_animation_setter.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
BackgroundAnimator::ChangeType change_type =
BackgroundAnimator::CHANGE_ANIMATE;
@@ -643,7 +611,6 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
update_shelf_observer_->Detach();
// UpdateShelfBackground deletes itself when the animation is done.
update_shelf_observer_ = new UpdateShelfObserver(this);
- status_animation_setter.AddObserver(update_shelf_observer_);
} else {
UpdateShelfBackground(change_type);
}
@@ -652,18 +619,10 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
state.visibility_state == SHELF_VISIBLE &&
state.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED);
- ui::Layer* layer = GetLayer(shelf_->status_area_widget());
- // TODO(harrym): Remove when status_area is view (crbug.com/180422).
- gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
- status_bounds.set_x(status_bounds.x() +
- target_bounds.shelf_bounds_in_root.x());
- status_bounds.set_y(status_bounds.y() +
- target_bounds.shelf_bounds_in_root.y());
- layer->SetBounds(status_bounds);
- layer->SetOpacity(target_bounds.status_opacity);
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- root_window_, target_bounds.work_area_insets);
- UpdateHitTestBounds();
+ TargetBounds target_bounds;
+ CalculateTargetBounds(state_, &target_bounds);
+ UpdateBoundsAndOpacity(target_bounds, true,
+ delay_background_change ? update_shelf_observer_ : NULL);
// OnAutoHideStateChanged Should be emitted when:
// - firstly state changed to auto-hide from other state
@@ -676,6 +635,58 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
}
}
+void ShelfLayoutManager::UpdateBoundsAndOpacity(
+ const TargetBounds& target_bounds,
+ bool animate,
+ ui::ImplicitAnimationObserver* observer) {
+ base::AutoReset<bool> auto_reset_updating_bounds(&updating_bounds_, true);
+
+ ui::ScopedLayerAnimationSettings launcher_animation_setter(
+ GetLayer(shelf_)->GetAnimator());
+ ui::ScopedLayerAnimationSettings status_animation_setter(
+ GetLayer(shelf_->status_area_widget())->GetAnimator());
+ if (animate) {
+ launcher_animation_setter.SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS));
+ launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
+ launcher_animation_setter.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ status_animation_setter.SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS));
+ status_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
+ status_animation_setter.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ } else {
+ StopAnimating();
+ launcher_animation_setter.SetTransitionDuration(base::TimeDelta());
+ status_animation_setter.SetTransitionDuration(base::TimeDelta());
+ }
+ if (observer)
+ status_animation_setter.AddObserver(observer);
+
+ GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
+ shelf_->SetBounds(ScreenAsh::ConvertRectToScreen(
+ shelf_->GetNativeView()->parent(),
+ target_bounds.shelf_bounds_in_root));
+
+ GetLayer(shelf_->status_area_widget())->SetOpacity(
+ target_bounds.status_opacity);
+ // TODO(harrym): Once status area widget is a child view of shelf
+ // this can be simplified.
+ gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
+ status_bounds.set_x(status_bounds.x() +
+ target_bounds.shelf_bounds_in_root.x());
+ status_bounds.set_y(status_bounds.y() +
+ target_bounds.shelf_bounds_in_root.y());
+ shelf_->status_area_widget()->SetBounds(
+ ScreenAsh::ConvertRectToScreen(
+ shelf_->status_area_widget()->GetNativeView()->parent(),
+ status_bounds));
+ Shell::GetInstance()->SetDisplayWorkAreaInsets(
+ root_window_, target_bounds.work_area_insets);
+ UpdateHitTestBounds();
+}
+
void ShelfLayoutManager::StopAnimating() {
GetLayer(shelf_)->GetAnimator()->StopAnimating();
GetLayer(shelf_->status_area_widget())->GetAnimator()->StopAnimating();
@@ -954,9 +965,6 @@ ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
if (visibility_state != SHELF_AUTO_HIDE || !shelf_)
return SHELF_AUTO_HIDE_HIDDEN;
- if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS)
- return gesture_drag_auto_hide_state_;
-
Shell* shell = Shell::GetInstance();
if (shell->GetAppListTargetVisibility())
return SHELF_AUTO_HIDE_SHOWN;
@@ -974,10 +982,36 @@ ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
if (shelf_->IsActive() || shelf_->status_area_widget()->IsActive())
return SHELF_AUTO_HIDE_SHOWN;
+ const std::vector<aura::Window*> windows =
+ ash::MruWindowTracker::BuildWindowList(false);
+
+ // Process the window list and check if there are any visible windows.
+ bool visible_window = false;
+ for (size_t i = 0; i < windows.size(); ++i) {
+ if (windows[i] && windows[i]->IsVisible() &&
+ !ash::wm::IsWindowMinimized(windows[i]) &&
+ root_window_ == windows[i]->GetRootWindow()) {
+ visible_window = true;
+ break;
+ }
+ }
+ // If there are no visible windows do not hide the shelf.
+ if (!visible_window)
+ return SHELF_AUTO_HIDE_SHOWN;
+
+ if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS)
+ return gesture_drag_auto_hide_state_;
+
// Don't show if the user is dragging the mouse.
if (auto_hide_event_filter_.get() && auto_hide_event_filter_->in_mouse_drag())
return SHELF_AUTO_HIDE_HIDDEN;
+ // Ignore the mouse position if mouse events are disabled.
+ aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
+ shelf_->GetNativeWindow()->GetRootWindow());
+ if (!cursor_client->IsMouseEventsEnabled())
+ return SHELF_AUTO_HIDE_HIDDEN;
sadrul 2013/08/13 17:21:34 This parts are from another CL, right?
pkotwicz 2013/08/14 17:03:21 That CL has now landed, rebasing is easier :)
+
gfx::Rect shelf_region = shelf_->GetWindowBoundsInScreen();
if (shelf_->status_area_widget() &&
shelf_->status_area_widget()->IsMessageBubbleShown() &&
@@ -1018,19 +1052,7 @@ ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
return SHELF_AUTO_HIDE_SHOWN;
}
- const std::vector<aura::Window*> windows =
- ash::MruWindowTracker::BuildWindowList(false);
-
- // Process the window list and check if there are any visible windows.
- for (size_t i = 0; i < windows.size(); ++i) {
- if (windows[i] && windows[i]->IsVisible() &&
- !ash::wm::IsWindowMinimized(windows[i]) &&
- root_window_ == windows[i]->GetRootWindow())
- return SHELF_AUTO_HIDE_HIDDEN;
- }
-
- // If there are no visible windows do not hide the shelf.
- return SHELF_AUTO_HIDE_SHOWN;
+ return SHELF_AUTO_HIDE_HIDDEN;
}
void ShelfLayoutManager::UpdateHitTestBounds() {

Powered by Google App Engine
This is Rietveld 408576698