Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/shelf/shelf_layout_manager.h" | 5 #include "ash/shelf/shelf_layout_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "ash/common/wm_lookup.h" | 21 #include "ash/common/wm_lookup.h" |
| 22 #include "ash/common/wm_root_window_controller.h" | 22 #include "ash/common/wm_root_window_controller.h" |
| 23 #include "ash/common/wm_root_window_controller_observer.h" | 23 #include "ash/common/wm_root_window_controller_observer.h" |
| 24 #include "ash/common/wm_shell.h" | 24 #include "ash/common/wm_shell.h" |
| 25 #include "ash/common/wm_window.h" | 25 #include "ash/common/wm_window.h" |
| 26 #include "ash/screen_util.h" | 26 #include "ash/screen_util.h" |
| 27 #include "ash/shelf/shelf.h" | 27 #include "ash/shelf/shelf.h" |
| 28 #include "ash/shelf/shelf_bezel_event_filter.h" | 28 #include "ash/shelf/shelf_bezel_event_filter.h" |
| 29 #include "ash/shelf/shelf_layout_manager_observer.h" | 29 #include "ash/shelf/shelf_layout_manager_observer.h" |
| 30 #include "ash/shell.h" | 30 #include "ash/shell.h" |
| 31 #include "ash/wm/gestures/shelf_gesture_handler.h" | |
| 32 #include "ash/wm/window_animations.h" | 31 #include "ash/wm/window_animations.h" |
| 33 #include "ash/wm/workspace_controller.h" | 32 #include "ash/wm/workspace_controller.h" |
| 34 #include "base/auto_reset.h" | 33 #include "base/auto_reset.h" |
| 35 #include "base/i18n/rtl.h" | 34 #include "base/i18n/rtl.h" |
| 36 #include "ui/compositor/layer.h" | 35 #include "ui/compositor/layer.h" |
| 37 #include "ui/compositor/layer_animation_observer.h" | 36 #include "ui/compositor/layer_animation_observer.h" |
| 38 #include "ui/compositor/layer_animator.h" | 37 #include "ui/compositor/layer_animator.h" |
| 39 #include "ui/compositor/scoped_layer_animation_settings.h" | 38 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 40 #include "ui/display/display.h" | 39 #include "ui/display/display.h" |
| 41 #include "ui/display/screen.h" | 40 #include "ui/display/screen.h" |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 SetState(SHELF_VISIBLE); | 294 SetState(SHELF_VISIBLE); |
| 296 } else if (WmShell::Get()->IsPinned()) { | 295 } else if (WmShell::Get()->IsPinned()) { |
| 297 SetState(SHELF_HIDDEN); | 296 SetState(SHELF_HIDDEN); |
| 298 } else { | 297 } else { |
| 299 // TODO(zelidrag): Verify shelf drag animation still shows on the device | 298 // TODO(zelidrag): Verify shelf drag animation still shows on the device |
| 300 // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN. | 299 // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN. |
| 301 wm::WorkspaceWindowState window_state( | 300 wm::WorkspaceWindowState window_state( |
| 302 workspace_controller_->GetWindowState()); | 301 workspace_controller_->GetWindowState()); |
| 303 switch (window_state) { | 302 switch (window_state) { |
| 304 case wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN: { | 303 case wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN: { |
| 305 const WmWindow* fullscreen_window = wm::GetWindowForFullscreenMode( | 304 if (IsShelfHiddenForFullscreen()) { |
| 306 WmLookup::Get()->GetWindowForWidget(shelf_widget_)); | |
| 307 if (fullscreen_window && | |
| 308 fullscreen_window->GetWindowState()->hide_shelf_when_fullscreen()) { | |
| 309 SetState(SHELF_HIDDEN); | 305 SetState(SHELF_HIDDEN); |
| 310 } else { | 306 } else { |
| 311 // The shelf is sometimes not hidden when in immersive fullscreen. | 307 // The shelf is sometimes not hidden when in immersive fullscreen. |
| 312 // Force the shelf to be auto hidden in this case. | 308 // Force the shelf to be auto hidden in this case. |
| 313 SetState(SHELF_AUTO_HIDE); | 309 SetState(SHELF_AUTO_HIDE); |
| 314 } | 310 } |
| 315 break; | 311 break; |
| 316 } | 312 } |
| 317 | 313 |
| 318 case wm::WORKSPACE_WINDOW_STATE_MAXIMIZED: | 314 case wm::WORKSPACE_WINDOW_STATE_MAXIMIZED: |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 } | 360 } |
| 365 } | 361 } |
| 366 | 362 |
| 367 void ShelfLayoutManager::UpdateAutoHideForGestureEvent( | 363 void ShelfLayoutManager::UpdateAutoHideForGestureEvent( |
| 368 ui::GestureEvent* event) { | 364 ui::GestureEvent* event) { |
| 369 if (visibility_state() != SHELF_AUTO_HIDE || in_shutdown_) | 365 if (visibility_state() != SHELF_AUTO_HIDE || in_shutdown_) |
| 370 return; | 366 return; |
| 371 | 367 |
| 372 aura::Window* target_window = static_cast<aura::Window*>(event->target()); | 368 aura::Window* target_window = static_cast<aura::Window*>(event->target()); |
| 373 if (IsShelfWindow(target_window)) { | 369 if (IsShelfWindow(target_window)) { |
| 374 if (gesture_handler_.ProcessGestureEvent(*event, target_window)) | 370 if (ProcessGestureEvent(*event)) |
|
msw
2016/08/05 23:48:49
optional nit: combine nested conditional with the
James Cook
2016/08/05 23:55:16
Done.
| |
| 375 event->StopPropagation(); | 371 event->StopPropagation(); |
| 376 } | 372 } |
| 377 } | 373 } |
| 378 | 374 |
| 379 void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) { | 375 void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) { |
| 380 window_overlaps_shelf_ = value; | 376 window_overlaps_shelf_ = value; |
| 381 UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); | 377 UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); |
| 382 } | 378 } |
| 383 | 379 |
| 384 void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) { | 380 void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) { |
| 385 observers_.AddObserver(observer); | 381 observers_.AddObserver(observer); |
| 386 } | 382 } |
| 387 | 383 |
| 388 void ShelfLayoutManager::RemoveObserver(ShelfLayoutManagerObserver* observer) { | 384 void ShelfLayoutManager::RemoveObserver(ShelfLayoutManagerObserver* observer) { |
| 389 observers_.RemoveObserver(observer); | 385 observers_.RemoveObserver(observer); |
| 390 } | 386 } |
| 391 | 387 |
| 392 //////////////////////////////////////////////////////////////////////////////// | 388 bool ShelfLayoutManager::ProcessGestureEvent(const ui::GestureEvent& event) { |
| 393 // ShelfLayoutManager, Gesture functions: | 389 // The gestures are disabled in the lock/login screen. |
| 390 SessionStateDelegate* delegate = WmShell::Get()->GetSessionStateDelegate(); | |
| 391 if (!delegate->NumberOfLoggedInUsers() || delegate->IsScreenLocked()) | |
| 392 return false; | |
| 394 | 393 |
| 395 void ShelfLayoutManager::OnGestureEdgeSwipe(const ui::GestureEvent& gesture) { | 394 if (IsShelfHiddenForFullscreen()) |
| 396 if (visibility_state() == SHELF_AUTO_HIDE) { | 395 return false; |
| 397 gesture_drag_auto_hide_state_ = SHELF_AUTO_HIDE_SHOWN; | |
| 398 gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS; | |
| 399 UpdateVisibilityState(); | |
| 400 gesture_drag_status_ = GESTURE_DRAG_NONE; | |
| 401 } | |
| 402 } | |
| 403 | 396 |
| 404 void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) { | 397 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
| 405 gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS; | 398 StartGestureDrag(event); |
| 406 gesture_drag_amount_ = 0.f; | 399 return true; |
| 407 gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE | |
| 408 ? auto_hide_state() | |
| 409 : SHELF_AUTO_HIDE_SHOWN; | |
| 410 UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); | |
| 411 } | |
| 412 | |
| 413 void ShelfLayoutManager::UpdateGestureDrag(const ui::GestureEvent& gesture) { | |
| 414 gesture_drag_amount_ += PrimaryAxisValue(gesture.details().scroll_y(), | |
| 415 gesture.details().scroll_x()); | |
| 416 LayoutShelf(); | |
| 417 } | |
| 418 | |
| 419 void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) { | |
| 420 bool horizontal = IsHorizontalAlignment(); | |
| 421 bool should_change = false; | |
| 422 if (gesture.type() == ui::ET_GESTURE_SCROLL_END) { | |
| 423 // The visibility of the shelf changes only if the shelf was dragged X% | |
| 424 // along the correct axis. If the shelf was already visible, then the | |
| 425 // direction of the drag does not matter. | |
| 426 const float kDragHideThreshold = 0.4f; | |
| 427 gfx::Rect bounds = GetIdealBounds(); | |
| 428 float drag_ratio = fabs(gesture_drag_amount_) / | |
| 429 (horizontal ? bounds.height() : bounds.width()); | |
| 430 if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) { | |
| 431 should_change = drag_ratio > kDragHideThreshold; | |
| 432 } else { | |
| 433 bool correct_direction = false; | |
| 434 switch (GetAlignment()) { | |
| 435 case SHELF_ALIGNMENT_BOTTOM: | |
| 436 case SHELF_ALIGNMENT_BOTTOM_LOCKED: | |
| 437 case SHELF_ALIGNMENT_RIGHT: | |
| 438 correct_direction = gesture_drag_amount_ < 0; | |
| 439 break; | |
| 440 case SHELF_ALIGNMENT_LEFT: | |
| 441 correct_direction = gesture_drag_amount_ > 0; | |
| 442 break; | |
| 443 } | |
| 444 should_change = correct_direction && drag_ratio > kDragHideThreshold; | |
| 445 } | |
| 446 } else if (gesture.type() == ui::ET_SCROLL_FLING_START) { | |
| 447 if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) { | |
| 448 should_change = horizontal ? fabs(gesture.details().velocity_y()) > 0 | |
| 449 : fabs(gesture.details().velocity_x()) > 0; | |
| 450 } else { | |
| 451 should_change = | |
| 452 SelectValueForShelfAlignment(gesture.details().velocity_y() < 0, | |
| 453 gesture.details().velocity_x() > 0, | |
| 454 gesture.details().velocity_x() < 0); | |
| 455 } | |
| 456 } else { | |
| 457 NOTREACHED(); | |
| 458 } | 400 } |
| 459 | 401 |
| 460 if (!should_change) { | 402 if (gesture_drag_status_ != GESTURE_DRAG_IN_PROGRESS) |
| 461 CancelGestureDrag(); | 403 return false; |
| 462 return; | 404 |
| 405 if (event.type() == ui::ET_GESTURE_SCROLL_UPDATE) { | |
| 406 UpdateGestureDrag(event); | |
| 407 return true; | |
| 463 } | 408 } |
| 464 if (shelf_widget_) { | 409 |
| 465 shelf_widget_->Deactivate(); | 410 if (event.type() == ui::ET_GESTURE_SCROLL_END || |
| 466 shelf_widget_->status_area_widget()->Deactivate(); | 411 event.type() == ui::ET_SCROLL_FLING_START) { |
| 412 CompleteGestureDrag(event); | |
| 413 return true; | |
| 467 } | 414 } |
| 468 gesture_drag_auto_hide_state_ = | |
| 469 gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN | |
| 470 ? SHELF_AUTO_HIDE_HIDDEN | |
| 471 : SHELF_AUTO_HIDE_SHOWN; | |
| 472 ShelfAutoHideBehavior new_auto_hide_behavior = | |
| 473 gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN | |
| 474 ? SHELF_AUTO_HIDE_BEHAVIOR_NEVER | |
| 475 : SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; | |
| 476 | 415 |
| 477 // When in fullscreen and the shelf is forced to be auto hidden, the auto hide | 416 // Unexpected event. Reset the state and let the event fall through. |
| 478 // behavior affects neither the visibility state nor the auto hide state. Set | 417 CancelGestureDrag(); |
| 479 // |gesture_drag_status_| to GESTURE_DRAG_COMPLETE_IN_PROGRESS to set the auto | 418 return false; |
| 480 // hide state to |gesture_drag_auto_hide_state_|. | |
| 481 gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS; | |
| 482 Shelf* shelf = shelf_widget_->shelf(); | |
| 483 if (shelf->auto_hide_behavior() != new_auto_hide_behavior) | |
| 484 shelf->SetAutoHideBehavior(new_auto_hide_behavior); | |
| 485 else | |
| 486 UpdateVisibilityState(); | |
| 487 gesture_drag_status_ = GESTURE_DRAG_NONE; | |
| 488 } | |
| 489 | |
| 490 void ShelfLayoutManager::CancelGestureDrag() { | |
| 491 gesture_drag_status_ = GESTURE_DRAG_CANCEL_IN_PROGRESS; | |
| 492 UpdateVisibilityState(); | |
| 493 gesture_drag_status_ = GESTURE_DRAG_NONE; | |
| 494 } | 419 } |
| 495 | 420 |
| 496 void ShelfLayoutManager::SetAnimationDurationOverride( | 421 void ShelfLayoutManager::SetAnimationDurationOverride( |
| 497 int duration_override_in_ms) { | 422 int duration_override_in_ms) { |
| 498 duration_override_in_ms_ = duration_override_in_ms; | 423 duration_override_in_ms_ = duration_override_in_ms; |
| 499 } | 424 } |
| 500 | 425 |
| 501 //////////////////////////////////////////////////////////////////////////////// | 426 //////////////////////////////////////////////////////////////////////////////// |
| 502 // ShelfLayoutManager, wm::WmSnapToPixelLayoutManager implementation: | 427 // ShelfLayoutManager, wm::WmSnapToPixelLayoutManager implementation: |
| 503 | 428 |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1184 // screen. | 1109 // screen. |
| 1185 if (ash::MaterialDesignController::IsShelfMaterial()) { | 1110 if (ash::MaterialDesignController::IsShelfMaterial()) { |
| 1186 return (state.visibility_state == SHELF_AUTO_HIDE && | 1111 return (state.visibility_state == SHELF_AUTO_HIDE && |
| 1187 state.auto_hide_state == SHELF_AUTO_HIDE_SHOWN) | 1112 state.auto_hide_state == SHELF_AUTO_HIDE_SHOWN) |
| 1188 ? 1.0f | 1113 ? 1.0f |
| 1189 : 0.0f; | 1114 : 0.0f; |
| 1190 } | 1115 } |
| 1191 return (state.visibility_state == SHELF_AUTO_HIDE) ? 1.0f : 0.0f; | 1116 return (state.visibility_state == SHELF_AUTO_HIDE) ? 1.0f : 0.0f; |
| 1192 } | 1117 } |
| 1193 | 1118 |
| 1119 bool ShelfLayoutManager::IsShelfHiddenForFullscreen() const { | |
| 1120 const WmWindow* fullscreen_window = wm::GetWindowForFullscreenMode( | |
| 1121 WmLookup::Get()->GetWindowForWidget(shelf_widget_)); | |
| 1122 return fullscreen_window && | |
| 1123 fullscreen_window->GetWindowState()->hide_shelf_when_fullscreen(); | |
| 1124 } | |
| 1125 | |
| 1126 //////////////////////////////////////////////////////////////////////////////// | |
| 1127 // ShelfLayoutManager, Gesture functions: | |
| 1128 | |
| 1129 void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) { | |
|
James Cook
2016/08/05 23:27:07
These methods are moved unchanged in order to matc
msw
2016/08/05 23:48:49
Acknowledged.
| |
| 1130 gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS; | |
| 1131 gesture_drag_amount_ = 0.f; | |
| 1132 gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE | |
| 1133 ? auto_hide_state() | |
| 1134 : SHELF_AUTO_HIDE_SHOWN; | |
| 1135 UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); | |
| 1136 } | |
| 1137 | |
| 1138 void ShelfLayoutManager::UpdateGestureDrag(const ui::GestureEvent& gesture) { | |
| 1139 gesture_drag_amount_ += PrimaryAxisValue(gesture.details().scroll_y(), | |
| 1140 gesture.details().scroll_x()); | |
| 1141 LayoutShelf(); | |
| 1142 } | |
| 1143 | |
| 1144 void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) { | |
| 1145 bool horizontal = IsHorizontalAlignment(); | |
| 1146 bool should_change = false; | |
| 1147 if (gesture.type() == ui::ET_GESTURE_SCROLL_END) { | |
| 1148 // The visibility of the shelf changes only if the shelf was dragged X% | |
| 1149 // along the correct axis. If the shelf was already visible, then the | |
| 1150 // direction of the drag does not matter. | |
| 1151 const float kDragHideThreshold = 0.4f; | |
| 1152 gfx::Rect bounds = GetIdealBounds(); | |
| 1153 float drag_ratio = fabs(gesture_drag_amount_) / | |
| 1154 (horizontal ? bounds.height() : bounds.width()); | |
| 1155 if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) { | |
| 1156 should_change = drag_ratio > kDragHideThreshold; | |
| 1157 } else { | |
| 1158 bool correct_direction = false; | |
| 1159 switch (GetAlignment()) { | |
| 1160 case SHELF_ALIGNMENT_BOTTOM: | |
| 1161 case SHELF_ALIGNMENT_BOTTOM_LOCKED: | |
| 1162 case SHELF_ALIGNMENT_RIGHT: | |
| 1163 correct_direction = gesture_drag_amount_ < 0; | |
| 1164 break; | |
| 1165 case SHELF_ALIGNMENT_LEFT: | |
| 1166 correct_direction = gesture_drag_amount_ > 0; | |
| 1167 break; | |
| 1168 } | |
| 1169 should_change = correct_direction && drag_ratio > kDragHideThreshold; | |
| 1170 } | |
| 1171 } else if (gesture.type() == ui::ET_SCROLL_FLING_START) { | |
| 1172 if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) { | |
| 1173 should_change = horizontal ? fabs(gesture.details().velocity_y()) > 0 | |
| 1174 : fabs(gesture.details().velocity_x()) > 0; | |
| 1175 } else { | |
| 1176 should_change = | |
| 1177 SelectValueForShelfAlignment(gesture.details().velocity_y() < 0, | |
| 1178 gesture.details().velocity_x() > 0, | |
| 1179 gesture.details().velocity_x() < 0); | |
| 1180 } | |
| 1181 } else { | |
| 1182 NOTREACHED(); | |
| 1183 } | |
| 1184 | |
| 1185 if (!should_change) { | |
| 1186 CancelGestureDrag(); | |
| 1187 return; | |
| 1188 } | |
| 1189 if (shelf_widget_) { | |
| 1190 shelf_widget_->Deactivate(); | |
| 1191 shelf_widget_->status_area_widget()->Deactivate(); | |
| 1192 } | |
| 1193 gesture_drag_auto_hide_state_ = | |
| 1194 gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN | |
| 1195 ? SHELF_AUTO_HIDE_HIDDEN | |
| 1196 : SHELF_AUTO_HIDE_SHOWN; | |
| 1197 ShelfAutoHideBehavior new_auto_hide_behavior = | |
| 1198 gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN | |
| 1199 ? SHELF_AUTO_HIDE_BEHAVIOR_NEVER | |
| 1200 : SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; | |
| 1201 | |
| 1202 // When in fullscreen and the shelf is forced to be auto hidden, the auto hide | |
| 1203 // behavior affects neither the visibility state nor the auto hide state. Set | |
| 1204 // |gesture_drag_status_| to GESTURE_DRAG_COMPLETE_IN_PROGRESS to set the auto | |
| 1205 // hide state to |gesture_drag_auto_hide_state_|. | |
| 1206 gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS; | |
| 1207 Shelf* shelf = shelf_widget_->shelf(); | |
| 1208 if (shelf->auto_hide_behavior() != new_auto_hide_behavior) | |
| 1209 shelf->SetAutoHideBehavior(new_auto_hide_behavior); | |
| 1210 else | |
| 1211 UpdateVisibilityState(); | |
| 1212 gesture_drag_status_ = GESTURE_DRAG_NONE; | |
| 1213 } | |
| 1214 | |
| 1215 void ShelfLayoutManager::CancelGestureDrag() { | |
| 1216 gesture_drag_status_ = GESTURE_DRAG_CANCEL_IN_PROGRESS; | |
| 1217 UpdateVisibilityState(); | |
| 1218 gesture_drag_status_ = GESTURE_DRAG_NONE; | |
| 1219 } | |
| 1220 | |
| 1194 } // namespace ash | 1221 } // namespace ash |
| OLD | NEW |