lock_window_state.cc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/wm/lock_window_state.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "ash/keyboard/ui/keyboard_ui_controller.h"
  8. #include "ash/public/cpp/window_animation_types.h"
  9. #include "ash/screen_util.h"
  10. #include "ash/shelf/shelf.h"
  11. #include "ash/shell.h"
  12. #include "ash/wm/lock_layout_manager.h"
  13. #include "ash/wm/window_state.h"
  14. #include "ash/wm/window_state_delegate.h"
  15. #include "ash/wm/window_state_util.h"
  16. #include "ash/wm/wm_event.h"
  17. #include "ash/wm/work_area_insets.h"
  18. #include "ui/aura/window.h"
  19. #include "ui/compositor/layer.h"
  20. #include "ui/gfx/geometry/rect.h"
  21. #include "ui/wm/core/coordinate_conversion.h"
  22. namespace ash {
  23. using ::chromeos::WindowStateType;
  24. LockWindowState::LockWindowState(aura::Window* window, bool exclude_shelf)
  25. : current_state_type_(WindowState::Get(window)->GetStateType()),
  26. exclude_shelf_(exclude_shelf) {}
  27. LockWindowState::~LockWindowState() = default;
  28. void LockWindowState::OnWMEvent(WindowState* window_state,
  29. const WMEvent* event) {
  30. switch (event->type()) {
  31. case WM_EVENT_TOGGLE_FULLSCREEN:
  32. ToggleFullScreen(window_state, window_state->delegate());
  33. break;
  34. case WM_EVENT_FULLSCREEN:
  35. UpdateWindow(window_state, WindowStateType::kFullscreen);
  36. break;
  37. case WM_EVENT_PIP:
  38. case WM_EVENT_FLOAT:
  39. case WM_EVENT_PIN:
  40. case WM_EVENT_TRUSTED_PIN:
  41. NOTREACHED();
  42. break;
  43. case WM_EVENT_TOGGLE_MAXIMIZE_CAPTION:
  44. case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
  45. case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
  46. case WM_EVENT_TOGGLE_MAXIMIZE:
  47. case WM_EVENT_CYCLE_SNAP_PRIMARY:
  48. case WM_EVENT_CYCLE_SNAP_SECONDARY:
  49. case WM_EVENT_CENTER:
  50. case WM_EVENT_SNAP_PRIMARY:
  51. case WM_EVENT_SNAP_SECONDARY:
  52. case WM_EVENT_NORMAL:
  53. case WM_EVENT_RESTORE:
  54. case WM_EVENT_MAXIMIZE:
  55. UpdateWindow(window_state,
  56. GetMaximizedOrCenteredWindowType(window_state));
  57. return;
  58. case WM_EVENT_MINIMIZE:
  59. UpdateWindow(window_state, WindowStateType::kMinimized);
  60. return;
  61. case WM_EVENT_SHOW_INACTIVE:
  62. return;
  63. case WM_EVENT_SET_BOUNDS:
  64. if (window_state->IsMaximized() || window_state->IsFullscreen()) {
  65. UpdateBounds(window_state);
  66. } else {
  67. const SetBoundsWMEvent* bounds_event =
  68. static_cast<const SetBoundsWMEvent*>(event);
  69. window_state->SetBoundsConstrained(bounds_event->requested_bounds());
  70. }
  71. break;
  72. case WM_EVENT_ADDED_TO_WORKSPACE:
  73. if (current_state_type_ != WindowStateType::kMaximized &&
  74. current_state_type_ != WindowStateType::kMinimized &&
  75. current_state_type_ != WindowStateType::kFullscreen) {
  76. UpdateWindow(window_state,
  77. GetMaximizedOrCenteredWindowType(window_state));
  78. } else {
  79. UpdateBounds(window_state);
  80. }
  81. break;
  82. case WM_EVENT_WORKAREA_BOUNDS_CHANGED:
  83. case WM_EVENT_DISPLAY_BOUNDS_CHANGED:
  84. UpdateBounds(window_state);
  85. break;
  86. case WM_EVENT_SYSTEM_UI_AREA_CHANGED:
  87. return;
  88. }
  89. }
  90. WindowStateType LockWindowState::GetType() const {
  91. return current_state_type_;
  92. }
  93. void LockWindowState::AttachState(WindowState* window_state,
  94. WindowState::State* previous_state) {
  95. current_state_type_ = previous_state->GetType();
  96. // Initialize the state to a good preset.
  97. if (current_state_type_ != WindowStateType::kMaximized &&
  98. current_state_type_ != WindowStateType::kMinimized &&
  99. current_state_type_ != WindowStateType::kFullscreen) {
  100. UpdateWindow(window_state, GetMaximizedOrCenteredWindowType(window_state));
  101. }
  102. }
  103. void LockWindowState::DetachState(WindowState* window_state) {}
  104. // static
  105. WindowState* LockWindowState::SetLockWindowState(aura::Window* window) {
  106. std::unique_ptr<WindowState::State> lock_state =
  107. std::make_unique<LockWindowState>(window, false);
  108. WindowState* window_state = WindowState::Get(window);
  109. std::unique_ptr<WindowState::State> old_state(
  110. window_state->SetStateObject(std::move(lock_state)));
  111. return window_state;
  112. }
  113. // static
  114. WindowState* LockWindowState::SetLockWindowStateWithShelfExcluded(
  115. aura::Window* window) {
  116. std::unique_ptr<WindowState::State> lock_state =
  117. std::make_unique<LockWindowState>(window, true);
  118. WindowState* window_state = WindowState::Get(window);
  119. std::unique_ptr<WindowState::State> old_state(
  120. window_state->SetStateObject(std::move(lock_state)));
  121. return window_state;
  122. }
  123. void LockWindowState::UpdateWindow(WindowState* window_state,
  124. WindowStateType target_state) {
  125. DCHECK(target_state == WindowStateType::kMinimized ||
  126. target_state == WindowStateType::kMaximized ||
  127. (target_state == WindowStateType::kNormal &&
  128. !window_state->CanMaximize()) ||
  129. target_state == WindowStateType::kFullscreen);
  130. if (target_state == WindowStateType::kMinimized) {
  131. if (current_state_type_ == WindowStateType::kMinimized)
  132. return;
  133. current_state_type_ = target_state;
  134. ::wm::SetWindowVisibilityAnimationType(
  135. window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
  136. window_state->window()->Hide();
  137. if (window_state->IsActive())
  138. window_state->Deactivate();
  139. return;
  140. }
  141. if (current_state_type_ == target_state) {
  142. // If the state type did not change, update it accordingly.
  143. UpdateBounds(window_state);
  144. return;
  145. }
  146. const WindowStateType old_state_type = current_state_type_;
  147. current_state_type_ = target_state;
  148. window_state->UpdateWindowPropertiesFromStateType();
  149. window_state->NotifyPreStateTypeChange(old_state_type);
  150. UpdateBounds(window_state);
  151. window_state->NotifyPostStateTypeChange(old_state_type);
  152. if ((window_state->window()->TargetVisibility() ||
  153. old_state_type == WindowStateType::kMinimized) &&
  154. !window_state->window()->layer()->visible()) {
  155. // The layer may be hidden if the window was previously minimized. Make
  156. // sure it's visible.
  157. window_state->window()->Show();
  158. }
  159. }
  160. WindowStateType LockWindowState::GetMaximizedOrCenteredWindowType(
  161. WindowState* window_state) {
  162. return window_state->CanMaximize() ? WindowStateType::kMaximized
  163. : WindowStateType::kNormal;
  164. }
  165. gfx::Rect LockWindowState::GetWindowBounds(aura::Window* window) {
  166. if (exclude_shelf_)
  167. return screen_util::GetDisplayWorkAreaBoundsInParentForLockScreen(window);
  168. auto* keyboard_controller = keyboard::KeyboardUIController::Get();
  169. const int keyboard_height =
  170. keyboard_controller->IsEnabled()
  171. ? keyboard_controller->GetKeyboardLockScreenOffsetBounds().height()
  172. : 0;
  173. gfx::Rect bounds = screen_util::GetDisplayBoundsWithShelf(window);
  174. gfx::Insets insets(WorkAreaInsets::ForWindow(window->GetRootWindow())
  175. ->GetAccessibilityInsets());
  176. if (keyboard_height > 0)
  177. insets.set_bottom(keyboard_height);
  178. bounds.Inset(insets);
  179. return bounds;
  180. }
  181. void LockWindowState::UpdateBounds(WindowState* window_state) {
  182. if (!window_state->IsMaximized() && !window_state->IsFullscreen())
  183. return;
  184. gfx::Rect bounds = GetWindowBounds(window_state->window());
  185. VLOG(1) << "Updating window bounds to: " << bounds.ToString();
  186. window_state->SetBoundsDirect(bounds);
  187. }
  188. } // namespace ash