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 21 matching lines...) Expand all Loading... | |
| 32 #include "ash/wm/workspace_controller.h" | 32 #include "ash/wm/workspace_controller.h" |
| 33 #include "base/auto_reset.h" | 33 #include "base/auto_reset.h" |
| 34 #include "base/i18n/rtl.h" | 34 #include "base/i18n/rtl.h" |
| 35 #include "ui/compositor/layer.h" | 35 #include "ui/compositor/layer.h" |
| 36 #include "ui/compositor/layer_animation_observer.h" | 36 #include "ui/compositor/layer_animation_observer.h" |
| 37 #include "ui/compositor/layer_animator.h" | 37 #include "ui/compositor/layer_animator.h" |
| 38 #include "ui/compositor/scoped_layer_animation_settings.h" | 38 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 39 #include "ui/display/display.h" | 39 #include "ui/display/display.h" |
| 40 #include "ui/display/screen.h" | 40 #include "ui/display/screen.h" |
| 41 #include "ui/events/event.h" | 41 #include "ui/events/event.h" |
| 42 #include "ui/events/event_handler.h" | |
| 43 #include "ui/keyboard/keyboard_util.h" | 42 #include "ui/keyboard/keyboard_util.h" |
| 44 #include "ui/views/border.h" | 43 #include "ui/views/border.h" |
| 45 #include "ui/views/widget/widget.h" | 44 #include "ui/views/widget/widget.h" |
| 46 | 45 |
| 47 namespace ash { | 46 namespace ash { |
| 48 namespace { | 47 namespace { |
| 49 | 48 |
| 50 // Delay before showing the shelf. This is after the mouse stops moving. | 49 // Delay before showing the shelf. This is after the mouse stops moving. |
| 51 const int kAutoHideDelayMS = 200; | 50 const int kAutoHideDelayMS = 200; |
| 52 | 51 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 66 // auto hidden shelf. The region is used to make it easier to trigger showing | 65 // auto hidden shelf. The region is used to make it easier to trigger showing |
| 67 // the auto hidden shelf when the shelf is on the boundary between displays. | 66 // the auto hidden shelf when the shelf is on the boundary between displays. |
| 68 const int kMaxAutoHideShowShelfRegionSize = 10; | 67 const int kMaxAutoHideShowShelfRegionSize = 10; |
| 69 | 68 |
| 70 ui::Layer* GetLayer(views::Widget* widget) { | 69 ui::Layer* GetLayer(views::Widget* widget) { |
| 71 return widget->GetNativeView()->layer(); | 70 return widget->GetNativeView()->layer(); |
| 72 } | 71 } |
| 73 | 72 |
| 74 } // namespace | 73 } // namespace |
| 75 | 74 |
| 76 // ShelfLayoutManager::AutoHideEventFilter ------------------------------------- | |
| 77 | |
| 78 // Notifies ShelfLayoutManager any time the mouse moves. Not used on mash. | |
| 79 // TODO(jamescook): Delete this once the mash implementation handles drags on | |
| 80 // and off the shelf. | |
| 81 class ShelfLayoutManager::AutoHideEventFilter : public ui::EventHandler { | |
| 82 public: | |
| 83 explicit AutoHideEventFilter(ShelfLayoutManager* shelf); | |
| 84 ~AutoHideEventFilter() override; | |
| 85 | |
| 86 // Returns true if the last mouse event was a mouse drag. | |
| 87 bool in_mouse_drag() const { return in_mouse_drag_; } | |
| 88 | |
| 89 // Overridden from ui::EventHandler: | |
| 90 void OnMouseEvent(ui::MouseEvent* event) override; | |
| 91 void OnGestureEvent(ui::GestureEvent* event) override; | |
| 92 | |
| 93 private: | |
| 94 ShelfLayoutManager* shelf_; | |
| 95 bool in_mouse_drag_; | |
| 96 DISALLOW_COPY_AND_ASSIGN(AutoHideEventFilter); | |
| 97 }; | |
| 98 | |
| 99 ShelfLayoutManager::AutoHideEventFilter::AutoHideEventFilter( | |
| 100 ShelfLayoutManager* shelf) | |
| 101 : shelf_(shelf), in_mouse_drag_(false) { | |
| 102 Shell::GetInstance()->AddPreTargetHandler(this); | |
| 103 } | |
| 104 | |
| 105 ShelfLayoutManager::AutoHideEventFilter::~AutoHideEventFilter() { | |
| 106 Shell::GetInstance()->RemovePreTargetHandler(this); | |
| 107 } | |
| 108 | |
| 109 void ShelfLayoutManager::AutoHideEventFilter::OnMouseEvent( | |
| 110 ui::MouseEvent* event) { | |
| 111 // This also checks IsShelfWindow() to make sure we don't attempt to hide the | |
| 112 // shelf if the mouse down occurs on the shelf. | |
| 113 in_mouse_drag_ = | |
| 114 (event->type() == ui::ET_MOUSE_DRAGGED || | |
| 115 (in_mouse_drag_ && event->type() != ui::ET_MOUSE_RELEASED && | |
| 116 event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)) && | |
| 117 !shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target())); | |
| 118 shelf_->UpdateAutoHideForMouseEvent(event); | |
| 119 } | |
| 120 | |
| 121 void ShelfLayoutManager::AutoHideEventFilter::OnGestureEvent( | |
| 122 ui::GestureEvent* event) { | |
| 123 shelf_->UpdateAutoHideForGestureEvent(event); | |
| 124 } | |
| 125 | |
| 126 // ShelfLayoutManager::UpdateShelfObserver ------------------------------------- | 75 // ShelfLayoutManager::UpdateShelfObserver ------------------------------------- |
| 127 | 76 |
| 128 // UpdateShelfObserver is used to delay updating the background until the | 77 // UpdateShelfObserver is used to delay updating the background until the |
| 129 // animation completes. | 78 // animation completes. |
| 130 class ShelfLayoutManager::UpdateShelfObserver | 79 class ShelfLayoutManager::UpdateShelfObserver |
| 131 : public ui::ImplicitAnimationObserver { | 80 : public ui::ImplicitAnimationObserver { |
| 132 public: | 81 public: |
| 133 explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) { | 82 explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) { |
| 134 shelf_->update_shelf_observer_ = this; | 83 shelf_->update_shelf_observer_ = this; |
| 135 } | 84 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 WmShell::Get()->RemoveShellObserver(this); | 171 WmShell::Get()->RemoveShellObserver(this); |
| 223 WmShell::Get()->RemoveLockStateObserver(this); | 172 WmShell::Get()->RemoveLockStateObserver(this); |
| 224 WmShell::Get()->GetSessionStateDelegate()->RemoveSessionStateObserver(this); | 173 WmShell::Get()->GetSessionStateDelegate()->RemoveSessionStateObserver(this); |
| 225 } | 174 } |
| 226 | 175 |
| 227 void ShelfLayoutManager::PrepareForShutdown() { | 176 void ShelfLayoutManager::PrepareForShutdown() { |
| 228 in_shutdown_ = true; | 177 in_shutdown_ = true; |
| 229 // Clear all event filters, otherwise sometimes those filters may catch | 178 // Clear all event filters, otherwise sometimes those filters may catch |
| 230 // synthesized mouse event and cause crashes during the shutdown. | 179 // synthesized mouse event and cause crashes during the shutdown. |
| 231 set_workspace_controller(NULL); | 180 set_workspace_controller(NULL); |
| 232 auto_hide_event_filter_.reset(); | |
| 233 bezel_event_filter_.reset(); | 181 bezel_event_filter_.reset(); |
| 234 // Stop observing changes to avoid updating a partially destructed shelf. | 182 // Stop observing changes to avoid updating a partially destructed shelf. |
| 235 WmShell::Get()->RemoveActivationObserver(this); | 183 WmShell::Get()->RemoveActivationObserver(this); |
| 236 } | 184 } |
| 237 | 185 |
| 238 bool ShelfLayoutManager::IsVisible() const { | 186 bool ShelfLayoutManager::IsVisible() const { |
| 239 // status_area_widget() may be NULL during the shutdown. | 187 // status_area_widget() may be NULL during the shutdown. |
| 240 return shelf_widget_->status_area_widget() && | 188 return shelf_widget_->status_area_widget() && |
| 241 shelf_widget_->status_area_widget()->IsVisible() && | 189 shelf_widget_->status_area_widget()->IsVisible() && |
| 242 (state_.visibility_state == SHELF_VISIBLE || | 190 (state_.visibility_state == SHELF_VISIBLE || |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 } | 287 } |
| 340 auto_hide_timer_.Start( | 288 auto_hide_timer_.Start( |
| 341 FROM_HERE, base::TimeDelta::FromMilliseconds(kAutoHideDelayMS), this, | 289 FROM_HERE, base::TimeDelta::FromMilliseconds(kAutoHideDelayMS), this, |
| 342 &ShelfLayoutManager::UpdateAutoHideStateNow); | 290 &ShelfLayoutManager::UpdateAutoHideStateNow); |
| 343 } | 291 } |
| 344 } else { | 292 } else { |
| 345 StopAutoHideTimer(); | 293 StopAutoHideTimer(); |
| 346 } | 294 } |
| 347 } | 295 } |
| 348 | 296 |
| 349 void ShelfLayoutManager::UpdateAutoHideForMouseEvent(ui::MouseEvent* event) { | 297 void ShelfLayoutManager::UpdateAutoHideForMouseEvent(ui::MouseEvent* event, |
| 298 WmWindow* target) { | |
| 299 // This also checks IsShelfWindow() to make sure we don't attempt to hide the | |
| 300 // shelf if the mouse down occurs on the shelf. | |
| 301 in_mouse_drag_ = (event->type() == ui::ET_MOUSE_DRAGGED || | |
| 302 (in_mouse_drag_ && event->type() != ui::ET_MOUSE_RELEASED && | |
| 303 event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)) && | |
| 304 !IsShelfWindow(target); | |
| 305 | |
| 350 // Don't update during shutdown because synthetic mouse events (e.g. mouse | 306 // Don't update during shutdown because synthetic mouse events (e.g. mouse |
| 351 // exit) may be generated during status area widget teardown. | 307 // exit) may be generated during status area widget teardown. |
| 352 if (visibility_state() != SHELF_AUTO_HIDE || in_shutdown_) | 308 if (visibility_state() != SHELF_AUTO_HIDE || in_shutdown_) |
| 353 return; | 309 return; |
| 354 | 310 |
| 355 if (event->type() == ui::ET_MOUSE_MOVED || | 311 if (event->type() == ui::ET_MOUSE_MOVED || |
| 356 event->type() == ui::ET_MOUSE_ENTERED || | 312 event->type() == ui::ET_MOUSE_ENTERED || |
| 357 event->type() == ui::ET_MOUSE_EXITED) { | 313 event->type() == ui::ET_MOUSE_EXITED) { |
| 358 UpdateAutoHideState(); | 314 UpdateAutoHideState(); |
| 359 } | 315 } |
| 360 } | 316 } |
| 361 | 317 |
| 362 void ShelfLayoutManager::UpdateAutoHideForGestureEvent( | 318 void ShelfLayoutManager::UpdateAutoHideForGestureEvent(ui::GestureEvent* event, |
| 363 ui::GestureEvent* event) { | 319 WmWindow* target) { |
| 364 if (visibility_state() != SHELF_AUTO_HIDE || in_shutdown_) | 320 if (visibility_state() != SHELF_AUTO_HIDE || in_shutdown_) |
| 365 return; | 321 return; |
| 366 | 322 |
| 367 aura::Window* target_window = static_cast<aura::Window*>(event->target()); | 323 if (IsShelfWindow(target) && ProcessGestureEvent(*event)) |
| 368 if (IsShelfWindow(target_window) && ProcessGestureEvent(*event)) | |
| 369 event->StopPropagation(); | 324 event->StopPropagation(); |
| 370 } | 325 } |
| 371 | 326 |
| 372 void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) { | 327 void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) { |
| 373 window_overlaps_shelf_ = value; | 328 window_overlaps_shelf_ = value; |
| 374 UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); | 329 UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE); |
| 375 } | 330 } |
| 376 | 331 |
| 377 void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) { | 332 void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) { |
| 378 observers_.AddObserver(observer); | 333 observers_.AddObserver(observer); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 537 bool force_update = | 492 bool force_update = |
| 538 (gesture_drag_status_ == GESTURE_DRAG_CANCEL_IN_PROGRESS || | 493 (gesture_drag_status_ == GESTURE_DRAG_CANCEL_IN_PROGRESS || |
| 539 gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS); | 494 gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS); |
| 540 | 495 |
| 541 if (!force_update && state_.Equals(state)) | 496 if (!force_update && state_.Equals(state)) |
| 542 return; // Nothing changed. | 497 return; // Nothing changed. |
| 543 | 498 |
| 544 FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, | 499 FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, |
| 545 WillChangeVisibilityState(visibility_state)); | 500 WillChangeVisibilityState(visibility_state)); |
| 546 | 501 |
| 547 // mash does not support global event handlers. It uses events on the shelf | |
| 548 // and status area widgets to update auto-hide. | |
| 549 if (!Shell::GetInstance()->in_mus()) { | |
| 550 if (state.visibility_state == SHELF_AUTO_HIDE) { | |
| 551 // When state is SHELF_AUTO_HIDE we need to track when the mouse is over | |
| 552 // the shelf to unhide it. AutoHideEventFilter does that for us. | |
| 553 if (!auto_hide_event_filter_) | |
| 554 auto_hide_event_filter_.reset(new AutoHideEventFilter(this)); | |
| 555 } else { | |
| 556 auto_hide_event_filter_.reset(NULL); | |
| 557 } | |
| 558 } | |
| 559 | |
| 560 StopAutoHideTimer(); | 502 StopAutoHideTimer(); |
| 561 | 503 |
| 562 State old_state = state_; | 504 State old_state = state_; |
| 563 state_ = state; | 505 state_ = state; |
| 564 | 506 |
| 565 BackgroundAnimatorChangeType change_type = BACKGROUND_CHANGE_ANIMATE; | 507 BackgroundAnimatorChangeType change_type = BACKGROUND_CHANGE_ANIMATE; |
| 566 bool delay_background_change = false; | 508 bool delay_background_change = false; |
| 567 | 509 |
| 568 // Do not animate the background when: | 510 // Do not animate the background when: |
| 569 // - Going from a hidden / auto hidden shelf in fullscreen to a visible shelf | 511 // - Going from a hidden / auto hidden shelf in fullscreen to a visible shelf |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 } | 924 } |
| 983 // If there are no visible windows do not hide the shelf. | 925 // If there are no visible windows do not hide the shelf. |
| 984 if (!visible_window) | 926 if (!visible_window) |
| 985 return SHELF_AUTO_HIDE_SHOWN; | 927 return SHELF_AUTO_HIDE_SHOWN; |
| 986 } | 928 } |
| 987 | 929 |
| 988 if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) | 930 if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) |
| 989 return gesture_drag_auto_hide_state_; | 931 return gesture_drag_auto_hide_state_; |
| 990 | 932 |
| 991 // Don't show if the user is dragging the mouse. | 933 // Don't show if the user is dragging the mouse. |
| 992 if (auto_hide_event_filter_.get() && auto_hide_event_filter_->in_mouse_drag()) | 934 if (in_mouse_drag_) |
|
James Cook
2016/08/09 19:47:58
Just to double-check: This function is already che
msw
2016/08/09 19:52:58
Yup, I went to add a |visibility_state == SHELF_AU
James Cook
2016/08/09 19:54:28
Nope, this is fine.
| |
| 993 return SHELF_AUTO_HIDE_HIDDEN; | 935 return SHELF_AUTO_HIDE_HIDDEN; |
| 994 | 936 |
| 995 // Ignore the mouse position if mouse events are disabled. | 937 // Ignore the mouse position if mouse events are disabled. |
| 996 if (!shelf_widget_->IsMouseEventsEnabled()) | 938 if (!shelf_widget_->IsMouseEventsEnabled()) |
| 997 return SHELF_AUTO_HIDE_HIDDEN; | 939 return SHELF_AUTO_HIDE_HIDDEN; |
| 998 | 940 |
| 999 gfx::Rect shelf_region = shelf_widget_->GetWindowBoundsInScreen(); | 941 gfx::Rect shelf_region = shelf_widget_->GetWindowBoundsInScreen(); |
| 1000 if (shelf_widget_->status_area_widget() && | 942 if (shelf_widget_->status_area_widget() && |
| 1001 shelf_widget_->status_area_widget()->IsMessageBubbleShown() && | 943 shelf_widget_->status_area_widget()->IsMessageBubbleShown() && |
| 1002 IsVisible()) { | 944 IsVisible()) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1030 if ((state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN || | 972 if ((state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN || |
| 1031 mouse_over_shelf_when_auto_hide_timer_started_) && | 973 mouse_over_shelf_when_auto_hide_timer_started_) && |
| 1032 GetAutoHideShowShelfRegionInScreen().Contains( | 974 GetAutoHideShowShelfRegionInScreen().Contains( |
| 1033 cursor_position_in_screen)) { | 975 cursor_position_in_screen)) { |
| 1034 return SHELF_AUTO_HIDE_SHOWN; | 976 return SHELF_AUTO_HIDE_SHOWN; |
| 1035 } | 977 } |
| 1036 | 978 |
| 1037 return SHELF_AUTO_HIDE_HIDDEN; | 979 return SHELF_AUTO_HIDE_HIDDEN; |
| 1038 } | 980 } |
| 1039 | 981 |
| 1040 bool ShelfLayoutManager::IsShelfWindow(aura::Window* window) { | 982 bool ShelfLayoutManager::IsShelfWindow(WmWindow* window) { |
| 1041 if (!window) | 983 if (!window) |
| 1042 return false; | 984 return false; |
| 1043 return (shelf_widget_ && | 985 WmWindow* shelf_window = WmLookup::Get()->GetWindowForWidget(shelf_widget_); |
| 1044 shelf_widget_->GetNativeWindow()->Contains(window)) || | 986 WmWindow* status_window = |
| 1045 (shelf_widget_->status_area_widget() && | 987 WmLookup::Get()->GetWindowForWidget(shelf_widget_->status_area_widget()); |
|
James Cook
2016/08/09 19:47:58
It seems like this function should either check fo
msw
2016/08/09 19:52:58
Ah yeah, good call.
| |
| 1046 shelf_widget_->status_area_widget()->GetNativeWindow()->Contains( | 988 return (shelf_window && shelf_window->Contains(window)) || |
| 1047 window)); | 989 (status_window && status_window->Contains(window)); |
| 1048 } | 990 } |
| 1049 | 991 |
| 1050 int ShelfLayoutManager::GetWorkAreaInsets(const State& state, int size) const { | 992 int ShelfLayoutManager::GetWorkAreaInsets(const State& state, int size) const { |
| 1051 if (state.visibility_state == SHELF_VISIBLE) | 993 if (state.visibility_state == SHELF_VISIBLE) |
| 1052 return size; | 994 return size; |
| 1053 if (state.visibility_state == SHELF_AUTO_HIDE) | 995 if (state.visibility_state == SHELF_AUTO_HIDE) |
| 1054 return GetShelfConstant(SHELF_INSETS_FOR_AUTO_HIDE); | 996 return GetShelfConstant(SHELF_INSETS_FOR_AUTO_HIDE); |
| 1055 return 0; | 997 return 0; |
| 1056 } | 998 } |
| 1057 | 999 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1212 gesture_drag_status_ = GESTURE_DRAG_NONE; | 1154 gesture_drag_status_ = GESTURE_DRAG_NONE; |
| 1213 } | 1155 } |
| 1214 | 1156 |
| 1215 void ShelfLayoutManager::CancelGestureDrag() { | 1157 void ShelfLayoutManager::CancelGestureDrag() { |
| 1216 gesture_drag_status_ = GESTURE_DRAG_CANCEL_IN_PROGRESS; | 1158 gesture_drag_status_ = GESTURE_DRAG_CANCEL_IN_PROGRESS; |
| 1217 UpdateVisibilityState(); | 1159 UpdateVisibilityState(); |
| 1218 gesture_drag_status_ = GESTURE_DRAG_NONE; | 1160 gesture_drag_status_ = GESTURE_DRAG_NONE; |
| 1219 } | 1161 } |
| 1220 | 1162 |
| 1221 } // namespace ash | 1163 } // namespace ash |
| OLD | NEW |