root_window_controller.cc 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  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
  3. // found in the LICENSE file.
  4. #include "ash/root_window_controller.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <queue>
  8. #include <vector>
  9. #include "ash/accessibility/chromevox/touch_exploration_controller.h"
  10. #include "ash/accessibility/chromevox/touch_exploration_manager.h"
  11. #include "ash/accessibility/ui/accessibility_panel_layout_manager.h"
  12. #include "ash/ambient/ambient_controller.h"
  13. #include "ash/app_list/app_list_controller_impl.h"
  14. #include "ash/app_menu/app_menu_model_adapter.h"
  15. #include "ash/constants/ash_constants.h"
  16. #include "ash/constants/ash_features.h"
  17. #include "ash/constants/ash_switches.h"
  18. #include "ash/focus_cycler.h"
  19. #include "ash/high_contrast/high_contrast_controller.h"
  20. #include "ash/host/ash_window_tree_host.h"
  21. #include "ash/keyboard/arc/arc_virtual_keyboard_container_layout_manager.h"
  22. #include "ash/keyboard/keyboard_controller_impl.h"
  23. #include "ash/keyboard/ui/keyboard_layout_manager.h"
  24. #include "ash/keyboard/ui/keyboard_ui_controller.h"
  25. #include "ash/keyboard/ui/keyboard_util.h"
  26. #include "ash/keyboard/virtual_keyboard_container_layout_manager.h"
  27. #include "ash/lock_screen_action/lock_screen_action_background_controller.h"
  28. #include "ash/login_status.h"
  29. #include "ash/public/cpp/app_menu_constants.h"
  30. #include "ash/public/cpp/shelf_types.h"
  31. #include "ash/public/cpp/shell_window_ids.h"
  32. #include "ash/public/cpp/window_properties.h"
  33. #include "ash/resources/vector_icons/vector_icons.h"
  34. #include "ash/root_window_settings.h"
  35. #include "ash/scoped_animation_disabler.h"
  36. #include "ash/screen_util.h"
  37. #include "ash/session/session_controller_impl.h"
  38. #include "ash/shelf/shelf.h"
  39. #include "ash/shelf/shelf_context_menu_model.h"
  40. #include "ash/shelf/shelf_layout_manager.h"
  41. #include "ash/shelf/shelf_widget.h"
  42. #include "ash/shelf/shelf_window_targeter.h"
  43. #include "ash/shell.h"
  44. #include "ash/strings/grit/ash_strings.h"
  45. #include "ash/style/ash_color_provider_source.h"
  46. #include "ash/system/status_area_widget.h"
  47. #include "ash/system/tray/tray_background_view.h"
  48. #include "ash/system/unified/unified_system_tray.h"
  49. #include "ash/touch/touch_hud_debug.h"
  50. #include "ash/touch/touch_hud_projection.h"
  51. #include "ash/touch/touch_observer_hud.h"
  52. #include "ash/wallpaper/wallpaper_widget_controller.h"
  53. #include "ash/wm/always_on_top_controller.h"
  54. #include "ash/wm/container_finder.h"
  55. #include "ash/wm/desks/desks_controller.h"
  56. #include "ash/wm/desks/desks_util.h"
  57. #include "ash/wm/fullscreen_window_finder.h"
  58. #include "ash/wm/lock_action_handler_layout_manager.h"
  59. #include "ash/wm/lock_layout_manager.h"
  60. #include "ash/wm/mru_window_tracker.h"
  61. #include "ash/wm/overlay_layout_manager.h"
  62. #include "ash/wm/overview/overview_controller.h"
  63. #include "ash/wm/overview/overview_session.h"
  64. #include "ash/wm/root_window_layout_manager.h"
  65. #include "ash/wm/splitview/split_view_controller.h"
  66. #include "ash/wm/splitview/split_view_utils.h"
  67. #include "ash/wm/stacking_controller.h"
  68. #include "ash/wm/switchable_windows.h"
  69. #include "ash/wm/system_modal_container_layout_manager.h"
  70. #include "ash/wm/system_wallpaper_controller.h"
  71. #include "ash/wm/tablet_mode/tablet_mode_controller.h"
  72. #include "ash/wm/window_properties.h"
  73. #include "ash/wm/window_state.h"
  74. #include "ash/wm/window_util.h"
  75. #include "ash/wm/work_area_insets.h"
  76. #include "ash/wm/workspace/workspace_layout_manager.h"
  77. #include "ash/wm/workspace_controller.h"
  78. #include "base/bind.h"
  79. #include "base/command_line.h"
  80. #include "base/cxx17_backports.h"
  81. #include "base/metrics/histogram_macros.h"
  82. #include "base/time/time.h"
  83. #include "ui/aura/client/aura_constants.h"
  84. #include "ui/aura/client/drag_drop_client.h"
  85. #include "ui/aura/client/screen_position_client.h"
  86. #include "ui/aura/client/window_types.h"
  87. #include "ui/aura/null_window_targeter.h"
  88. #include "ui/aura/window.h"
  89. #include "ui/aura/window_event_dispatcher.h"
  90. #include "ui/aura/window_observer.h"
  91. #include "ui/aura/window_tracker.h"
  92. #include "ui/base/l10n/l10n_util.h"
  93. #include "ui/base/models/menu_model.h"
  94. #include "ui/base/models/simple_menu_model.h"
  95. #include "ui/compositor/layer.h"
  96. #include "ui/display/types/display_constants.h"
  97. #include "ui/events/event_utils.h"
  98. #include "ui/views/controls/menu/menu_model_adapter.h"
  99. #include "ui/views/controls/menu/menu_runner.h"
  100. #include "ui/views/view_model.h"
  101. #include "ui/views/view_model_utils.h"
  102. #include "ui/views/widget/widget.h"
  103. #include "ui/wm/core/capture_controller.h"
  104. #include "ui/wm/core/coordinate_conversion.h"
  105. #include "ui/wm/core/visibility_controller.h"
  106. #include "ui/wm/core/window_properties.h"
  107. #include "ui/wm/core/window_util.h"
  108. #include "ui/wm/public/tooltip_client.h"
  109. namespace ash {
  110. namespace {
  111. bool IsInShelfContainer(aura::Window* container) {
  112. if (!container)
  113. return false;
  114. int id = container->GetId();
  115. if (id == ash::kShellWindowId_ShelfContainer ||
  116. id == ash::kShellWindowId_ShelfBubbleContainer) {
  117. return true;
  118. }
  119. return IsInShelfContainer(container->parent());
  120. }
  121. bool IsWindowAboveContainer(aura::Window* window,
  122. aura::Window* blocking_container) {
  123. std::vector<aura::Window*> target_path;
  124. std::vector<aura::Window*> blocking_path;
  125. while (window) {
  126. target_path.push_back(window);
  127. window = window->parent();
  128. }
  129. while (blocking_container) {
  130. blocking_path.push_back(blocking_container);
  131. blocking_container = blocking_container->parent();
  132. }
  133. // The root window is put at the end so that we compare windows at
  134. // the same depth.
  135. while (!blocking_path.empty()) {
  136. if (target_path.empty())
  137. return false;
  138. aura::Window* target = target_path.back();
  139. target_path.pop_back();
  140. aura::Window* blocking = blocking_path.back();
  141. blocking_path.pop_back();
  142. // Still on the same path, continue.
  143. if (target == blocking)
  144. continue;
  145. // This can happen only if unparented window is passed because
  146. // first element must be the same root.
  147. if (!target->parent() || !blocking->parent())
  148. return false;
  149. aura::Window* common_parent = target->parent();
  150. DCHECK_EQ(common_parent, blocking->parent());
  151. const aura::Window::Windows& windows = common_parent->children();
  152. auto blocking_iter = std::find(windows.begin(), windows.end(), blocking);
  153. // If the target window is above blocking window, the window can handle
  154. // events.
  155. return std::find(blocking_iter, windows.end(), target) != windows.end();
  156. }
  157. return true;
  158. }
  159. // Scales |value| that is originally between 0 and |src_max| to be between
  160. // 0 and |dst_max|.
  161. float ToRelativeValue(int value, int src_max, int dst_max) {
  162. return static_cast<float>(value) / static_cast<float>(src_max) * dst_max;
  163. }
  164. // Uses ToRelativeValue() to scale the origin of |bounds_in_out|. The
  165. // width/height are not changed.
  166. void MoveOriginRelativeToSize(const gfx::Size& src_size,
  167. const gfx::Size& dst_size,
  168. gfx::Rect* bounds_in_out) {
  169. gfx::Point origin = bounds_in_out->origin();
  170. bounds_in_out->set_origin(gfx::Point(
  171. ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
  172. ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
  173. }
  174. // Reparents |window| to |new_parent|.
  175. void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
  176. const gfx::Size src_size = window->parent()->bounds().size();
  177. const gfx::Size dst_size = new_parent->bounds().size();
  178. // Update the restore bounds to make it relative to the display.
  179. WindowState* state = WindowState::Get(window);
  180. gfx::Rect restore_bounds;
  181. const bool has_restore_bounds = state && state->HasRestoreBounds();
  182. const bool update_bounds =
  183. state && (state->IsNormalOrSnapped() || state->IsMinimized());
  184. gfx::Rect work_area_in_new_parent =
  185. screen_util::GetDisplayWorkAreaBoundsInParent(new_parent);
  186. gfx::Rect local_bounds;
  187. if (update_bounds) {
  188. local_bounds = state->window()->bounds();
  189. MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
  190. local_bounds.AdjustToFit(work_area_in_new_parent);
  191. }
  192. if (has_restore_bounds) {
  193. restore_bounds = state->GetRestoreBoundsInParent();
  194. MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
  195. restore_bounds.AdjustToFit(work_area_in_new_parent);
  196. }
  197. new_parent->AddChild(window);
  198. // Docked windows have bounds handled by the layout manager in AddChild().
  199. if (update_bounds)
  200. window->SetBounds(local_bounds);
  201. if (has_restore_bounds)
  202. state->SetRestoreBoundsInParent(restore_bounds);
  203. }
  204. // Reparents the appropriate set of windows from |src| to |dst|.
  205. void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
  206. // Set of windows to move.
  207. constexpr int kContainerIdsToMove[] = {
  208. kShellWindowId_AlwaysOnTopContainer,
  209. kShellWindowId_FloatContainer,
  210. kShellWindowId_PipContainer,
  211. kShellWindowId_SystemModalContainer,
  212. kShellWindowId_LockSystemModalContainer,
  213. kShellWindowId_UnparentedContainer,
  214. kShellWindowId_OverlayContainer,
  215. kShellWindowId_LockActionHandlerContainer,
  216. kShellWindowId_MenuContainer,
  217. };
  218. constexpr int kExtraContainerIdsToMoveInUnifiedMode[] = {
  219. kShellWindowId_LockScreenContainer,
  220. };
  221. // Desk container ids are different depends on whether Bento feature is
  222. // enabled or not.
  223. std::vector<int> container_ids = desks_util::GetDesksContainersIds();
  224. for (const int id : kContainerIdsToMove)
  225. container_ids.emplace_back(id);
  226. // Check the display mode as this is also necessary when trasitioning between
  227. // mirror and unified mode.
  228. if (Shell::Get()->display_manager()->current_default_multi_display_mode() ==
  229. display::DisplayManager::UNIFIED) {
  230. for (const int id : kExtraContainerIdsToMoveInUnifiedMode)
  231. container_ids.emplace_back(id);
  232. }
  233. const std::vector<aura::Window*> mru_list =
  234. Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kAllDesks);
  235. for (int id : container_ids) {
  236. aura::Window* src_container = src->GetChildById(id);
  237. aura::Window* dst_container = dst->GetChildById(id);
  238. const bool switchable_container = IsSwitchableContainer(src_container);
  239. while (!src_container->children().empty()) {
  240. // Restart iteration from the source container windows each time as they
  241. // may change as a result of moving other windows.
  242. const aura::Window::Windows& src_container_children =
  243. src_container->children();
  244. auto iter = src_container_children.rbegin();
  245. while (iter != src_container_children.rend() &&
  246. SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
  247. ++iter;
  248. }
  249. // If the entire window list is modal background windows then stop.
  250. if (iter == src_container_children.rend())
  251. break;
  252. // |iter| is invalidated after ReparentWindow. Cache it to use afterwards.
  253. aura::Window* const window = *iter;
  254. ReparentWindow(window, dst_container);
  255. aura::Window* stacking_target = nullptr;
  256. if (switchable_container) {
  257. // Find the first window that comes after |window| in the MRU list that
  258. // shares the same parent.
  259. bool found_window = false;
  260. for (aura::Window* window_iter : mru_list) {
  261. // First determine the position of |window| in the |mru_list|.
  262. if (!found_window && window == window_iter) {
  263. found_window = true;
  264. continue;
  265. }
  266. if (!found_window || window_iter->parent() != dst_container)
  267. continue;
  268. // Once |window| is found, the next item in |mru_list| with the same
  269. // parent (container) is the stacking target.
  270. stacking_target = window_iter;
  271. break;
  272. }
  273. }
  274. // |stacking_target| may be null if |switchable_container| is false, which
  275. // means the children of that container wouldn't be in the MRU list or if
  276. // |window| was the last item in the MRU list with parent id |id|. In
  277. // this case stack |window| at the bottom.
  278. if (stacking_target)
  279. dst_container->StackChildAbove(window, stacking_target);
  280. else
  281. dst_container->StackChildAtBottom(window);
  282. }
  283. }
  284. }
  285. bool ShouldDestroyWindowInCloseChildWindows(aura::Window* window) {
  286. return window->owned_by_parent();
  287. }
  288. // Clears the workspace controllers from the properties of all virtual desks
  289. // containers in |root|.
  290. void ClearWorkspaceControllers(aura::Window* root) {
  291. for (auto* desk_container : desks_util::GetDesksContainers(root))
  292. SetWorkspaceController(desk_container, nullptr);
  293. }
  294. class RootWindowTargeter : public aura::WindowTargeter {
  295. public:
  296. RootWindowTargeter() = default;
  297. RootWindowTargeter(const RootWindowTargeter&) = delete;
  298. RootWindowTargeter& operator=(const RootWindowTargeter&) = delete;
  299. ~RootWindowTargeter() override = default;
  300. protected:
  301. aura::Window* FindTargetForLocatedEvent(aura::Window* window,
  302. ui::LocatedEvent* event) override {
  303. if (!window->parent() && !window->bounds().Contains(event->location()) &&
  304. IsEventInsideDisplayForTelemetryHack(window, event)) {
  305. auto* dispatcher = window->GetHost()->dispatcher();
  306. bool has_capture_target = !!dispatcher->mouse_pressed_handler() ||
  307. !!aura::client::GetCaptureWindow(window);
  308. // Make sure that event location is within the root window bounds if
  309. // 1) mouse event isn't captured.
  310. // 2) A mouse is clicked without movement and capture.
  311. //
  312. // The event can be outside on some scale factor due to rounding, or due
  313. // to not well calibrated a touch screen, or Detect this situation and
  314. // adjust the location.
  315. bool bounded_click = ShouldConstrainMouseClick(event, has_capture_target);
  316. if (!has_capture_target || bounded_click) {
  317. gfx::Point new_location =
  318. FitPointToBounds(event->location(), window->bounds());
  319. // Do not change |location_f|. It's used to compute pixel position and
  320. // such client should know what they're doing.
  321. event->set_location(new_location);
  322. event->set_root_location(new_location);
  323. }
  324. }
  325. return aura::WindowTargeter::FindTargetForLocatedEvent(window, event);
  326. }
  327. // Stop-gap workaround for telemetry tests that send events far outside of the
  328. // display (e.g. 512, -4711). Fix the test and remove this (crbgu.com/904623).
  329. bool IsEventInsideDisplayForTelemetryHack(aura::Window* window,
  330. ui::LocatedEvent* event) {
  331. constexpr int ExtraMarginForTelemetryTest = -10;
  332. gfx::Rect bounds = window->bounds();
  333. bounds.Inset(ExtraMarginForTelemetryTest);
  334. return bounds.Contains(event->location());
  335. }
  336. private:
  337. // Returns true if the mouse event should be constrainted.
  338. bool ShouldConstrainMouseClick(ui::LocatedEvent* event,
  339. bool has_capture_target) {
  340. if (event->type() == ui::ET_MOUSE_PRESSED && !has_capture_target) {
  341. last_mouse_event_type_ = ui::ET_MOUSE_PRESSED;
  342. return true;
  343. }
  344. if (last_mouse_event_type_ == ui::ET_MOUSE_PRESSED &&
  345. event->type() == ui::ET_MOUSE_RELEASED && has_capture_target) {
  346. last_mouse_event_type_ = ui::ET_UNKNOWN;
  347. return true;
  348. }
  349. // For other cases, reset the state
  350. if (event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)
  351. last_mouse_event_type_ = ui::ET_UNKNOWN;
  352. return false;
  353. }
  354. gfx::Point FitPointToBounds(const gfx::Point p, const gfx::Rect& bounds) {
  355. return gfx::Point(base::clamp(p.x(), bounds.x(), bounds.right() - 1),
  356. base::clamp(p.y(), bounds.y(), bounds.bottom() - 1));
  357. }
  358. ui::EventType last_mouse_event_type_ = ui::ET_UNKNOWN;
  359. };
  360. class RootWindowMenuModelAdapter : public AppMenuModelAdapter {
  361. public:
  362. RootWindowMenuModelAdapter(std::unique_ptr<ui::SimpleMenuModel> model,
  363. views::Widget* widget_owner,
  364. ui::MenuSourceType source_type,
  365. base::OnceClosure on_menu_closed_callback,
  366. bool is_tablet_mode)
  367. : AppMenuModelAdapter(std::string(),
  368. std::move(model),
  369. widget_owner,
  370. source_type,
  371. std::move(on_menu_closed_callback),
  372. is_tablet_mode) {}
  373. RootWindowMenuModelAdapter(const RootWindowMenuModelAdapter&) = delete;
  374. RootWindowMenuModelAdapter& operator=(const RootWindowMenuModelAdapter&) =
  375. delete;
  376. ~RootWindowMenuModelAdapter() override = default;
  377. private:
  378. // AppMenuModelAdapter overrides:
  379. void RecordHistogramOnMenuClosed() override {
  380. const base::TimeDelta user_journey_time =
  381. base::TimeTicks::Now() - menu_open_time();
  382. UMA_HISTOGRAM_TIMES("Apps.ContextMenuUserJourneyTime.Desktop",
  383. user_journey_time);
  384. UMA_HISTOGRAM_ENUMERATION("Apps.ContextMenuShowSource.Desktop",
  385. source_type(), ui::MENU_SOURCE_TYPE_LAST);
  386. if (is_tablet_mode()) {
  387. UMA_HISTOGRAM_TIMES("Apps.ContextMenuUserJourneyTime.Desktop.TabletMode",
  388. user_journey_time);
  389. UMA_HISTOGRAM_ENUMERATION("Apps.ContextMenuShowSource.Desktop.TabletMode",
  390. source_type(), ui::MENU_SOURCE_TYPE_LAST);
  391. } else {
  392. UMA_HISTOGRAM_TIMES(
  393. "Apps.ContextMenuUserJourneyTime.Desktop.ClamshellMode",
  394. user_journey_time);
  395. UMA_HISTOGRAM_ENUMERATION(
  396. "Apps.ContextMenuShowSource.Desktop.ClamshellMode", source_type(),
  397. ui::MENU_SOURCE_TYPE_LAST);
  398. }
  399. }
  400. };
  401. // A layout manager that fills its container when the child window's resize
  402. // behavior is set to be maximizable.
  403. class FillLayoutManager : public aura::LayoutManager {
  404. public:
  405. explicit FillLayoutManager(aura::Window* container) : container_(container) {}
  406. ~FillLayoutManager() override = default;
  407. FillLayoutManager(const FillLayoutManager&) = delete;
  408. FillLayoutManager& operator=(const FillLayoutManager&) = delete;
  409. // aura::LayoutManager:
  410. void OnWindowResized() override { Relayout(); }
  411. void OnWindowAddedToLayout(aura::Window* child) override { Relayout(); }
  412. void OnWillRemoveWindowFromLayout(aura::Window* child) override {}
  413. void OnWindowRemovedFromLayout(aura::Window* child) override {}
  414. void OnChildWindowVisibilityChanged(aura::Window* child,
  415. bool visible) override {}
  416. void SetChildBounds(aura::Window* child,
  417. const gfx::Rect& requested_bounds) override {}
  418. private:
  419. void Relayout() {
  420. // Fill the window that is set to be maximizable.
  421. const gfx::Rect fullscreen(container_->bounds().size());
  422. for (auto* child : container_->children()) {
  423. const int resize_behavior =
  424. child->GetProperty(aura::client::kResizeBehaviorKey);
  425. if (resize_behavior & aura::client::kResizeBehaviorCanMaximize)
  426. SetChildBoundsDirect(child, fullscreen);
  427. }
  428. }
  429. aura::Window* container_;
  430. };
  431. } // namespace
  432. // static
  433. std::vector<RootWindowController*>*
  434. RootWindowController::root_window_controllers_ = nullptr;
  435. RootWindowController::~RootWindowController() {
  436. Shutdown();
  437. DCHECK(!wallpaper_widget_controller_.get());
  438. work_area_insets_.reset();
  439. ash_host_.reset();
  440. // The CaptureClient needs to be around for as long as the RootWindow is
  441. // valid.
  442. capture_client_.reset();
  443. root_window_controllers_->erase(std::find(root_window_controllers_->begin(),
  444. root_window_controllers_->end(),
  445. this));
  446. }
  447. RootWindowController* RootWindowController::CreateForPrimaryDisplay(
  448. AshWindowTreeHost* host) {
  449. RootWindowController* controller = new RootWindowController(host);
  450. controller->Init(RootWindowType::PRIMARY);
  451. return controller;
  452. }
  453. RootWindowController* RootWindowController::CreateForSecondaryDisplay(
  454. AshWindowTreeHost* host) {
  455. RootWindowController* controller = new RootWindowController(host);
  456. controller->Init(RootWindowType::SECONDARY);
  457. return controller;
  458. }
  459. // static
  460. RootWindowController* RootWindowController::ForWindow(
  461. const aura::Window* window) {
  462. DCHECK(window);
  463. CHECK(Shell::HasInstance());
  464. return GetRootWindowSettings(window->GetRootWindow())->controller;
  465. }
  466. // static
  467. RootWindowController* RootWindowController::ForTargetRootWindow() {
  468. CHECK(Shell::HasInstance());
  469. return ForWindow(Shell::GetRootWindowForNewWindows());
  470. }
  471. aura::WindowTreeHost* RootWindowController::GetHost() {
  472. return window_tree_host_;
  473. }
  474. const aura::WindowTreeHost* RootWindowController::GetHost() const {
  475. return window_tree_host_;
  476. }
  477. aura::Window* RootWindowController::GetRootWindow() {
  478. return GetHost()->window();
  479. }
  480. const aura::Window* RootWindowController::GetRootWindow() const {
  481. return GetHost()->window();
  482. }
  483. ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
  484. return shelf_->shelf_layout_manager();
  485. }
  486. SystemModalContainerLayoutManager*
  487. RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
  488. aura::Window* modal_container = nullptr;
  489. if (window) {
  490. aura::Window* window_container = GetContainerForWindow(window);
  491. if (window_container &&
  492. window_container->GetId() >= kShellWindowId_LockScreenContainer) {
  493. modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
  494. } else {
  495. modal_container = GetContainer(kShellWindowId_SystemModalContainer);
  496. }
  497. } else {
  498. int modal_window_id =
  499. Shell::Get()->session_controller()->IsUserSessionBlocked()
  500. ? kShellWindowId_LockSystemModalContainer
  501. : kShellWindowId_SystemModalContainer;
  502. modal_container = GetContainer(modal_window_id);
  503. }
  504. return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
  505. modal_container->layout_manager())
  506. : nullptr;
  507. }
  508. StatusAreaWidget* RootWindowController::GetStatusAreaWidget() {
  509. ShelfWidget* shelf_widget = shelf_->shelf_widget();
  510. return shelf_widget ? shelf_widget->status_area_widget() : nullptr;
  511. }
  512. bool RootWindowController::IsSystemTrayVisible() {
  513. TrayBackgroundView* tray = GetStatusAreaWidget()->unified_system_tray();
  514. return tray && tray->GetWidget()->IsVisible() && tray->GetVisible();
  515. }
  516. bool RootWindowController::CanWindowReceiveEvents(aura::Window* window) {
  517. if (GetRootWindow() != window->GetRootWindow())
  518. return false;
  519. aura::Window* blocking_container = nullptr;
  520. aura::Window* modal_container = nullptr;
  521. window_util::GetBlockingContainersForRoot(
  522. GetRootWindow(), &blocking_container, &modal_container);
  523. SystemModalContainerLayoutManager* modal_layout_manager = nullptr;
  524. modal_layout_manager = static_cast<SystemModalContainerLayoutManager*>(
  525. modal_container->layout_manager());
  526. if (modal_layout_manager->has_window_dimmer())
  527. blocking_container = modal_container;
  528. else
  529. modal_container = nullptr; // Don't check modal dialogs.
  530. // In normal session.
  531. if (!blocking_container)
  532. return true;
  533. if (!IsWindowAboveContainer(window, blocking_container))
  534. return false;
  535. if (modal_container) {
  536. // If the window is in the target modal container, only allow the top most
  537. // one.
  538. if (modal_container->Contains(window))
  539. return modal_layout_manager->IsPartOfActiveModalWindow(window);
  540. // Don't allow shelf to process events if there is a visible modal dialog.
  541. if (IsInShelfContainer(window->parent()))
  542. return false;
  543. }
  544. return true;
  545. }
  546. aura::Window* RootWindowController::FindEventTarget(
  547. const gfx::Point& location_in_screen) {
  548. gfx::Point location_in_root(location_in_screen);
  549. aura::Window* root_window = GetRootWindow();
  550. ::wm::ConvertPointFromScreen(root_window, &location_in_root);
  551. ui::MouseEvent test_event(ui::ET_MOUSE_MOVED, location_in_root,
  552. location_in_root, ui::EventTimeForNow(),
  553. ui::EF_NONE, ui::EF_NONE);
  554. ui::EventTarget* event_handler =
  555. root_window->GetHost()
  556. ->dispatcher()
  557. ->GetDefaultEventTargeter()
  558. ->FindTargetForEvent(root_window, &test_event);
  559. return static_cast<aura::Window*>(event_handler);
  560. }
  561. gfx::Point RootWindowController::GetLastMouseLocationInRoot() {
  562. return window_tree_host_->dispatcher()->GetLastMouseLocationInRoot();
  563. }
  564. aura::Window* RootWindowController::GetContainer(int container_id) {
  565. return GetRootWindow()->GetChildById(container_id);
  566. }
  567. const aura::Window* RootWindowController::GetContainer(int container_id) const {
  568. return window_tree_host_->window()->GetChildById(container_id);
  569. }
  570. void RootWindowController::Shutdown() {
  571. auto targeter = GetRootWindow()->SetEventTargeter(
  572. std::make_unique<aura::NullWindowTargeter>());
  573. touch_exploration_manager_.reset();
  574. wallpaper_widget_controller_.reset();
  575. CloseAmbientWidget(/*immediately=*/true);
  576. CloseChildWindows();
  577. aura::Window* root_window = GetRootWindow();
  578. GetRootWindowSettings(root_window)->controller = nullptr;
  579. // Forget with the display ID so that display lookup
  580. // ends up with invalid display.
  581. GetRootWindowSettings(root_window)->display_id = display::kInvalidDisplayId;
  582. if (ash_host_)
  583. ash_host_->PrepareForShutdown();
  584. system_wallpaper_.reset();
  585. lock_screen_action_background_controller_.reset();
  586. aura::client::SetScreenPositionClient(root_window, nullptr);
  587. // The targeter may still on the stack, so delete it later.
  588. if (targeter) {
  589. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
  590. std::move(targeter));
  591. }
  592. }
  593. void RootWindowController::CloseChildWindows() {
  594. // Child windows can be closed by secondary monitor disconnection, Shell
  595. // shutdown, or both. Avoid running the related cleanup code twice.
  596. if (did_close_child_windows_)
  597. return;
  598. did_close_child_windows_ = true;
  599. aura::Window* root = GetRootWindow();
  600. Shell::Get()->desks_controller()->OnRootWindowClosing(root);
  601. // Notify the keyboard controller before closing child windows and shutting
  602. // down associated layout managers.
  603. Shell::Get()->keyboard_controller()->OnRootWindowClosing(root);
  604. OverviewController* overview_controller = Shell::Get()->overview_controller();
  605. if (overview_controller && overview_controller->InOverviewSession())
  606. overview_controller->overview_session()->OnRootWindowClosing(root);
  607. shelf_->ShutdownShelfWidget();
  608. ClearWorkspaceControllers(root);
  609. always_on_top_controller_->ClearLayoutManagers();
  610. // Explicitly destroy top level windows. We do this because such windows may
  611. // query the RootWindow for state.
  612. aura::WindowTracker non_toplevel_windows;
  613. non_toplevel_windows.Add(root);
  614. while (!non_toplevel_windows.windows().empty()) {
  615. aura::Window* non_toplevel_window = non_toplevel_windows.Pop();
  616. aura::WindowTracker toplevel_windows;
  617. for (aura::Window* child : non_toplevel_window->children()) {
  618. if (!ShouldDestroyWindowInCloseChildWindows(child))
  619. continue;
  620. if (child->delegate())
  621. toplevel_windows.Add(child);
  622. else
  623. non_toplevel_windows.Add(child);
  624. }
  625. while (!toplevel_windows.windows().empty())
  626. delete toplevel_windows.Pop();
  627. }
  628. // Reset layout manager so that it won't fire unnecessary layout evetns.
  629. root->SetLayoutManager(nullptr);
  630. // And then remove the containers.
  631. while (!root->children().empty()) {
  632. aura::Window* child = root->children()[0];
  633. if (ShouldDestroyWindowInCloseChildWindows(child))
  634. delete child;
  635. else
  636. root->RemoveChild(child);
  637. }
  638. // Removing the containers destroys ShelfLayoutManager. ShelfWidget outlives
  639. // ShelfLayoutManager because ShelfLayoutManager holds a pointer to it.
  640. shelf_->DestroyShelfWidget();
  641. ::wm::SetTooltipClient(GetRootWindow(), nullptr);
  642. }
  643. void RootWindowController::MoveWindowsTo(aura::Window* dst) {
  644. // Suspend unnecessary updates of the shelf visibility indefinitely since it
  645. // is going away.
  646. if (GetShelfLayoutManager())
  647. GetShelfLayoutManager()->SuspendVisibilityUpdateForShutdown();
  648. // Clear the workspace controller to avoid a lot of unnecessary operations
  649. // when window are removed.
  650. // TODO(afakhry): Should we also clear the WorkspaceLayoutManagers of the pip,
  651. // always-on-top, and other containers?
  652. aura::Window* root = GetRootWindow();
  653. ClearWorkspaceControllers(root);
  654. ReparentAllWindows(root, dst);
  655. }
  656. void RootWindowController::InitTouchHuds() {
  657. // Enable touch debugging features when each display is initialized.
  658. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  659. if (command_line->HasSwitch(switches::kAshTouchHud))
  660. set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
  661. // TouchHudProjection manages its own lifetime.
  662. if (command_line->HasSwitch(switches::kShowTaps))
  663. touch_hud_projection_ = new TouchHudProjection(GetRootWindow());
  664. }
  665. aura::Window* RootWindowController::GetWindowForFullscreenMode() {
  666. return GetWindowForFullscreenModeInRoot(GetRootWindow());
  667. }
  668. bool RootWindowController::IsInFullscreenMode() {
  669. auto* window = GetWindowForFullscreenMode();
  670. return window && WindowState::Get(window)->GetHideShelfWhenFullscreen();
  671. }
  672. void RootWindowController::SetTouchAccessibilityAnchorPoint(
  673. const gfx::Point& anchor_point) {
  674. if (touch_exploration_manager_)
  675. touch_exploration_manager_->SetTouchAccessibilityAnchorPoint(anchor_point);
  676. }
  677. void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
  678. ui::MenuSourceType source_type) {
  679. const int64_t display_id = display::Screen::GetScreen()
  680. ->GetDisplayNearestWindow(GetRootWindow())
  681. .id();
  682. const bool tablet_mode =
  683. Shell::Get()->tablet_mode_controller()->InTabletMode();
  684. root_window_menu_model_adapter_ =
  685. std::make_unique<RootWindowMenuModelAdapter>(
  686. std::make_unique<ShelfContextMenuModel>(nullptr, display_id),
  687. wallpaper_widget_controller()->GetWidget(), source_type,
  688. base::BindOnce(&RootWindowController::OnMenuClosed,
  689. base::Unretained(this)),
  690. tablet_mode);
  691. // Appends the apps sort options in ShelfContextMenuModel in tablet mode. Note
  692. // that the launcher UI is fullscreen in tablet mode, so the whole root window
  693. // can be perceived by users to be part of the launcher.
  694. auto* const app_list_controller = Shell::Get()->app_list_controller();
  695. if (features::IsLauncherAppSortEnabled() && tablet_mode &&
  696. app_list_controller->IsVisible(display_id) &&
  697. app_list_controller->GetCurrentAppListPage() ==
  698. AppListState::kStateApps) {
  699. ui::SimpleMenuModel* menu_model = root_window_menu_model_adapter_->model();
  700. sort_apps_submenu_ = std::make_unique<ui::SimpleMenuModel>(
  701. static_cast<ShelfContextMenuModel*>(menu_model));
  702. sort_apps_submenu_->AddItemWithIcon(
  703. REORDER_BY_NAME_ALPHABETICAL,
  704. l10n_util::GetStringUTF16(
  705. IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_BY_NAME),
  706. ui::ImageModel::FromVectorIcon(kSortAlphabeticalIcon,
  707. ui::kColorAshSystemUIMenuIcon));
  708. sort_apps_submenu_->AddItemWithIcon(
  709. REORDER_BY_COLOR,
  710. l10n_util::GetStringUTF16(
  711. IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_BY_COLOR),
  712. ui::ImageModel::FromVectorIcon(kSortColorIcon,
  713. ui::kColorAshSystemUIMenuIcon));
  714. menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
  715. menu_model->AddSubMenuWithIcon(
  716. REORDER_SUBMENU,
  717. l10n_util::GetStringUTF16(
  718. IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_TITLE),
  719. sort_apps_submenu_.get(),
  720. ui::ImageModel::FromVectorIcon(kReorderIcon,
  721. ui::kColorAshSystemUIMenuIcon));
  722. // Append the "Show all suggestions" / "Hide all suggestions" item.
  723. if (features::IsLauncherHideContinueSectionEnabled()) {
  724. menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
  725. if (app_list_controller->ShouldHideContinueSection()) {
  726. menu_model->AddItemWithIcon(
  727. ShelfContextMenuModel::MENU_SHOW_CONTINUE_SECTION,
  728. l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_SHOW_CONTINUE_SECTION),
  729. ui::ImageModel::FromVectorIcon(kLauncherShowContinueSectionIcon,
  730. ui::kColorAshSystemUIMenuIcon));
  731. } else {
  732. menu_model->AddItemWithIcon(
  733. ShelfContextMenuModel::MENU_HIDE_CONTINUE_SECTION,
  734. l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_HIDE_CONTINUE_SECTION),
  735. ui::ImageModel::FromVectorIcon(kLauncherHideContinueSectionIcon,
  736. ui::kColorAshSystemUIMenuIcon));
  737. }
  738. }
  739. }
  740. root_window_menu_model_adapter_->Run(
  741. gfx::Rect(location_in_screen, gfx::Size()),
  742. views::MenuAnchorPosition::kBubbleRight,
  743. views::MenuRunner::CONTEXT_MENU |
  744. views::MenuRunner::USE_ASH_SYS_UI_LAYOUT |
  745. views::MenuRunner::FIXED_ANCHOR);
  746. }
  747. void RootWindowController::HideContextMenu() {
  748. if (root_window_menu_model_adapter_)
  749. root_window_menu_model_adapter_->Cancel();
  750. }
  751. void RootWindowController::HideContextMenuNoAnimation() {
  752. if (!IsContextMenuShown())
  753. return;
  754. views::Widget* submenu_widget =
  755. root_window_menu_model_adapter_->GetSubmenuWidget();
  756. DCHECK(submenu_widget);
  757. ScopedAnimationDisabler disable(submenu_widget->GetNativeWindow());
  758. root_window_menu_model_adapter_->Cancel();
  759. }
  760. bool RootWindowController::IsContextMenuShown() const {
  761. return root_window_menu_model_adapter_ &&
  762. root_window_menu_model_adapter_->IsShowingMenu();
  763. }
  764. void RootWindowController::UpdateAfterLoginStatusChange(LoginStatus status) {
  765. StatusAreaWidget* status_area_widget =
  766. shelf_->shelf_widget()->status_area_widget();
  767. if (status_area_widget)
  768. status_area_widget->UpdateAfterLoginStatusChange(status);
  769. }
  770. void RootWindowController::CreateAmbientWidget() {
  771. DCHECK(!ambient_widget_);
  772. auto* ambient_controller = Shell::Get()->ambient_controller();
  773. if (ambient_controller && ambient_controller->IsShown()) {
  774. ambient_widget_ = ambient_controller->CreateWidget(
  775. GetRootWindow()->GetChildById(kShellWindowId_AmbientModeContainer));
  776. }
  777. }
  778. void RootWindowController::CloseAmbientWidget(bool immediately) {
  779. if (ambient_widget_) {
  780. if (immediately)
  781. ambient_widget_->CloseNow();
  782. else
  783. ambient_widget_->CloseWithReason(views::Widget::ClosedReason::kLostFocus);
  784. }
  785. ambient_widget_.reset();
  786. }
  787. bool RootWindowController::HasAmbientWidget() const {
  788. return !!ambient_widget_;
  789. }
  790. AccessibilityPanelLayoutManager*
  791. RootWindowController::GetAccessibilityPanelLayoutManagerForTest() {
  792. return GetAccessibilityPanelLayoutManager();
  793. }
  794. ////////////////////////////////////////////////////////////////////////////////
  795. // RootWindowController, private:
  796. RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
  797. : ash_host_(ash_host),
  798. window_tree_host_(ash_host->AsWindowTreeHost()),
  799. shelf_(std::make_unique<Shelf>()),
  800. lock_screen_action_background_controller_(
  801. LockScreenActionBackgroundController::Create()),
  802. work_area_insets_(std::make_unique<WorkAreaInsets>(this)) {
  803. DCHECK(ash_host_);
  804. DCHECK(window_tree_host_);
  805. if (!root_window_controllers_)
  806. root_window_controllers_ = new std::vector<RootWindowController*>;
  807. root_window_controllers_->push_back(this);
  808. aura::Window* root_window = GetRootWindow();
  809. GetRootWindowSettings(root_window)->controller = this;
  810. stacking_controller_ = std::make_unique<StackingController>();
  811. aura::client::SetWindowParentingClient(root_window,
  812. stacking_controller_.get());
  813. capture_client_ = std::make_unique<::wm::ScopedCaptureClient>(root_window);
  814. }
  815. void RootWindowController::Init(RootWindowType root_window_type) {
  816. aura::Window* root_window = GetRootWindow();
  817. // Create |split_view_controller_| for every display.
  818. split_view_controller_ = std::make_unique<SplitViewController>(root_window);
  819. Shell* shell = Shell::Get();
  820. shell->InitRootWindow(root_window);
  821. auto old_targeter =
  822. root_window->SetEventTargeter(std::make_unique<RootWindowTargeter>());
  823. DCHECK(!old_targeter);
  824. CreateContainers();
  825. CreateSystemWallpaper(root_window_type);
  826. InitLayoutManagers();
  827. InitTouchHuds();
  828. // `shelf_` was created in the constructor.
  829. shelf_->shelf_widget()->PostCreateShelf();
  830. color_provider_source_ = std::make_unique<AshColorProviderSource>();
  831. if (Shell::GetPrimaryRootWindowController()
  832. ->GetSystemModalLayoutManager(nullptr)
  833. ->has_window_dimmer()) {
  834. GetSystemModalLayoutManager(nullptr)->CreateModalBackground();
  835. }
  836. wallpaper_widget_controller_ =
  837. std::make_unique<WallpaperWidgetController>(root_window);
  838. wallpaper_widget_controller_->Init(
  839. Shell::Get()->session_controller()->IsUserSessionBlocked());
  840. root_window_layout_manager_->OnWindowResized();
  841. CreateAmbientWidget();
  842. // Explicitly update the desks controller before notifying the ShellObservers.
  843. // This is to make sure the desks' states are correct before clients are
  844. // updated.
  845. Shell::Get()->desks_controller()->OnRootWindowAdded(root_window);
  846. if (root_window_type == RootWindowType::PRIMARY) {
  847. shell->keyboard_controller()->RebuildKeyboardIfEnabled();
  848. } else {
  849. window_tree_host_->Show();
  850. // Notify shell observers about new root window.
  851. shell->OnRootWindowAdded(root_window);
  852. }
  853. if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
  854. switches::kAshDisableTouchExplorationMode)) {
  855. touch_exploration_manager_ =
  856. std::make_unique<TouchExplorationManager>(this);
  857. }
  858. }
  859. void RootWindowController::InitLayoutManagers() {
  860. // Create the shelf and status area widgets. Creates the ShelfLayoutManager
  861. // as a side-effect.
  862. DCHECK(!shelf_->shelf_widget());
  863. aura::Window* root = GetRootWindow();
  864. shelf_->CreateShelfWidget(root);
  865. root->SetLayoutManager(root_window_layout_manager_);
  866. for (auto* container : desks_util::GetDesksContainers(root)) {
  867. // Installs WorkspaceLayoutManager on the container.
  868. SetWorkspaceController(container, new WorkspaceController(container));
  869. }
  870. aura::Window* modal_container =
  871. GetContainer(kShellWindowId_SystemModalContainer);
  872. modal_container->SetLayoutManager(
  873. new SystemModalContainerLayoutManager(modal_container));
  874. aura::Window* lock_modal_container =
  875. GetContainer(kShellWindowId_LockSystemModalContainer);
  876. DCHECK(lock_modal_container);
  877. lock_modal_container->SetLayoutManager(
  878. new SystemModalContainerLayoutManager(lock_modal_container));
  879. aura::Window* lock_action_handler_container =
  880. GetContainer(kShellWindowId_LockActionHandlerContainer);
  881. DCHECK(lock_action_handler_container);
  882. lock_screen_action_background_controller_->SetParentWindow(
  883. lock_action_handler_container);
  884. lock_action_handler_container->SetLayoutManager(
  885. new LockActionHandlerLayoutManager(
  886. lock_action_handler_container, shelf_.get(),
  887. lock_screen_action_background_controller_.get()));
  888. aura::Window* lock_container =
  889. GetContainer(kShellWindowId_LockScreenContainer);
  890. DCHECK(lock_container);
  891. lock_container->SetLayoutManager(
  892. new LockLayoutManager(lock_container, shelf_.get()));
  893. aura::Window* always_on_top_container =
  894. GetContainer(kShellWindowId_AlwaysOnTopContainer);
  895. aura::Window* pip_container = GetContainer(kShellWindowId_PipContainer);
  896. DCHECK(always_on_top_container);
  897. DCHECK(pip_container);
  898. always_on_top_controller_ = std::make_unique<AlwaysOnTopController>(
  899. always_on_top_container, pip_container);
  900. // Make it easier to resize windows that partially overlap the shelf. Must
  901. // occur after the ShelfLayoutManager is constructed by ShelfWidget.
  902. aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
  903. shelf_container->SetEventTargeter(
  904. std::make_unique<ShelfWindowTargeter>(shelf_container, shelf_.get()));
  905. }
  906. void RootWindowController::CreateContainers() {
  907. aura::Window* root = GetRootWindow();
  908. root_window_layout_manager_ = new RootWindowLayoutManager(root);
  909. // Add a NOT_DRAWN layer in between the root_window's layer and its current
  910. // children so that we only need to initiate two LayerAnimationSequences for
  911. // fullscreen animations such as the screen rotation animation and the desk
  912. // switch animation. Those animations take a screenshot of this container,
  913. // stack it ontop and animate the screenshot instead of the individual
  914. // elements.
  915. aura::Window* screen_rotation_container =
  916. CreateContainer(kShellWindowId_ScreenAnimationContainer,
  917. "ScreenAnimationContainer", root);
  918. // Everything that needs to be included in the docked magnifier, when enabled,
  919. // should be a descendant of MagnifiedContainer. The DockedMagnifierContainer
  920. // should not be a descendant of this container, otherwise there would be a
  921. // cycle (docked magnifier trying to magnify itself).
  922. aura::Window* magnified_container =
  923. CreateContainer(kShellWindowId_MagnifiedContainer, "MagnifiedContainer",
  924. screen_rotation_container);
  925. CreateContainer(kShellWindowId_DockedMagnifierContainer,
  926. "DockedMagnifierContainer", screen_rotation_container);
  927. // These containers are just used by PowerButtonController to animate groups
  928. // of containers simultaneously without messing up the current transformations
  929. // on those containers. These are direct children of the magnified_container
  930. // window; all of the other containers are their children.
  931. // The wallpaper container is not part of the lock animation, so it is not
  932. // included in those animate groups. When the screen is locked, the wallpaper
  933. // is moved to the lock screen wallpaper container (and moved back on unlock).
  934. // Ensure that there's an opaque layer occluding the non-lock-screen layers.
  935. aura::Window* wallpaper_container =
  936. CreateContainer(kShellWindowId_WallpaperContainer, "WallpaperContainer",
  937. magnified_container);
  938. ::wm::SetChildWindowVisibilityChangesAnimated(wallpaper_container);
  939. wallpaper_container->SetLayoutManager(
  940. new FillLayoutManager(wallpaper_container));
  941. if (features::AreGlanceablesEnabled()) {
  942. aura::Window* glanceables_container =
  943. CreateContainer(kShellWindowId_GlanceablesContainer,
  944. "GlanceablesContainer", magnified_container);
  945. glanceables_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  946. glanceables_container->SetLayoutManager(
  947. new FillLayoutManager(glanceables_container)); // Takes ownership.
  948. }
  949. aura::Window* non_lock_screen_containers =
  950. CreateContainer(kShellWindowId_NonLockScreenContainersContainer,
  951. "NonLockScreenContainersContainer", magnified_container);
  952. // Clip all windows inside this container, as half pixel of the window's
  953. // texture may become visible when the screen is scaled. crbug.com/368591.
  954. non_lock_screen_containers->layer()->SetMasksToBounds(true);
  955. aura::Window* lock_wallpaper_container =
  956. CreateContainer(kShellWindowId_LockScreenWallpaperContainer,
  957. "LockScreenWallpaperContainer", magnified_container);
  958. ::wm::SetChildWindowVisibilityChangesAnimated(lock_wallpaper_container);
  959. lock_wallpaper_container->SetLayoutManager(
  960. new FillLayoutManager(lock_wallpaper_container));
  961. aura::Window* lock_screen_containers =
  962. CreateContainer(kShellWindowId_LockScreenContainersContainer,
  963. "LockScreenContainersContainer", magnified_container);
  964. aura::Window* lock_screen_related_containers = CreateContainer(
  965. kShellWindowId_LockScreenRelatedContainersContainer,
  966. "LockScreenRelatedContainersContainer", magnified_container);
  967. aura::Window* app_list_tablet_mode_container =
  968. CreateContainer(kShellWindowId_HomeScreenContainer, "HomeScreenContainer",
  969. non_lock_screen_containers);
  970. app_list_tablet_mode_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
  971. true);
  972. CreateContainer(kShellWindowId_UnparentedContainer, "UnparentedContainer",
  973. non_lock_screen_containers);
  974. for (const auto& id : desks_util::GetDesksContainersIds()) {
  975. aura::Window* container = CreateContainer(
  976. id, desks_util::GetDeskContainerName(id), non_lock_screen_containers);
  977. ::wm::SetChildWindowVisibilityChangesAnimated(container);
  978. container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  979. container->SetProperty(kForceVisibleInMiniViewKey, true);
  980. window_util::SetChildrenUseExtendedHitRegionForWindow(container);
  981. // Hide the non-active containers.
  982. if (id != desks_util::GetActiveDeskContainerId())
  983. container->Hide();
  984. }
  985. aura::Window* always_on_top_container =
  986. CreateContainer(kShellWindowId_AlwaysOnTopContainer,
  987. "AlwaysOnTopContainer", non_lock_screen_containers);
  988. ::wm::SetChildWindowVisibilityChangesAnimated(always_on_top_container);
  989. always_on_top_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  990. aura::Window* float_container =
  991. CreateContainer(kShellWindowId_FloatContainer, "FloatContainer",
  992. non_lock_screen_containers);
  993. wm::SetChildWindowVisibilityChangesAnimated(float_container);
  994. float_container->SetProperty(wm::kUsesScreenCoordinatesKey, true);
  995. aura::Window* app_list_container =
  996. CreateContainer(kShellWindowId_AppListContainer, "AppListContainer",
  997. non_lock_screen_containers);
  998. app_list_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  999. aura::Window* pip_container = CreateContainer(
  1000. kShellWindowId_PipContainer, "PipContainer", non_lock_screen_containers);
  1001. ::wm::SetChildWindowVisibilityChangesAnimated(pip_container);
  1002. pip_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1003. aura::Window* arc_ime_parent_container = CreateContainer(
  1004. kShellWindowId_ArcImeWindowParentContainer, "ArcImeWindowParentContainer",
  1005. non_lock_screen_containers);
  1006. arc_ime_parent_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1007. arc_ime_parent_container->SetLayoutManager(
  1008. new ArcVirtualKeyboardContainerLayoutManager(arc_ime_parent_container));
  1009. aura::Window* arc_vk_container =
  1010. CreateContainer(kShellWindowId_ArcVirtualKeyboardContainer,
  1011. "ArcVirtualKeyboardContainer", arc_ime_parent_container);
  1012. arc_vk_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1013. aura::Window* shelf_container_parent = lock_screen_related_containers;
  1014. aura::Window* shelf_container = CreateContainer(
  1015. kShellWindowId_ShelfContainer, "ShelfContainer", shelf_container_parent);
  1016. shelf_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1017. shelf_container->SetProperty(kLockedToRootKey, true);
  1018. aura::Window* shelf_bubble_container =
  1019. CreateContainer(kShellWindowId_ShelfBubbleContainer,
  1020. "ShelfBubbleContainer", non_lock_screen_containers);
  1021. shelf_bubble_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1022. shelf_bubble_container->SetProperty(kLockedToRootKey, true);
  1023. aura::Window* modal_container =
  1024. CreateContainer(kShellWindowId_SystemModalContainer,
  1025. "SystemModalContainer", non_lock_screen_containers);
  1026. ::wm::SetChildWindowVisibilityChangesAnimated(modal_container);
  1027. modal_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1028. window_util::SetChildrenUseExtendedHitRegionForWindow(modal_container);
  1029. aura::Window* lock_container =
  1030. CreateContainer(kShellWindowId_LockScreenContainer, "LockScreenContainer",
  1031. lock_screen_containers);
  1032. lock_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1033. aura::Window* lock_action_handler_container =
  1034. CreateContainer(kShellWindowId_LockActionHandlerContainer,
  1035. "LockActionHandlerContainer", lock_screen_containers);
  1036. ::wm::SetChildWindowVisibilityChangesAnimated(lock_action_handler_container);
  1037. lock_action_handler_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
  1038. true);
  1039. aura::Window* lock_modal_container =
  1040. CreateContainer(kShellWindowId_LockSystemModalContainer,
  1041. "LockSystemModalContainer", lock_screen_containers);
  1042. ::wm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
  1043. lock_modal_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1044. window_util::SetChildrenUseExtendedHitRegionForWindow(lock_modal_container);
  1045. aura::Window* power_menu_container =
  1046. CreateContainer(kShellWindowId_PowerMenuContainer, "PowerMenuContainer",
  1047. lock_screen_related_containers);
  1048. power_menu_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1049. aura::Window* settings_bubble_container =
  1050. CreateContainer(kShellWindowId_SettingBubbleContainer,
  1051. "SettingBubbleContainer", lock_screen_related_containers);
  1052. ::wm::SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
  1053. settings_bubble_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1054. settings_bubble_container->SetProperty(kLockedToRootKey, true);
  1055. aura::Window* virtual_keyboard_parent_container = CreateContainer(
  1056. kShellWindowId_ImeWindowParentContainer, "ImeWindowParentContainer",
  1057. lock_screen_related_containers);
  1058. virtual_keyboard_parent_container->SetProperty(
  1059. ::wm::kUsesScreenCoordinatesKey, true);
  1060. virtual_keyboard_parent_container->SetLayoutManager(
  1061. new VirtualKeyboardContainerLayoutManager(
  1062. virtual_keyboard_parent_container));
  1063. aura::Window* virtual_keyboard_container = CreateContainer(
  1064. kShellWindowId_VirtualKeyboardContainer, "VirtualKeyboardContainer",
  1065. virtual_keyboard_parent_container);
  1066. virtual_keyboard_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
  1067. true);
  1068. virtual_keyboard_container->SetLayoutManager(
  1069. new keyboard::KeyboardLayoutManager(
  1070. keyboard::KeyboardUIController::Get()));
  1071. aura::Window* accessibility_panel_container = CreateContainer(
  1072. kShellWindowId_AccessibilityPanelContainer, "AccessibilityPanelContainer",
  1073. lock_screen_related_containers);
  1074. ::wm::SetChildWindowVisibilityChangesAnimated(accessibility_panel_container);
  1075. accessibility_panel_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
  1076. true);
  1077. accessibility_panel_container->SetProperty(kLockedToRootKey, true);
  1078. accessibility_panel_container->SetLayoutManager(
  1079. new AccessibilityPanelLayoutManager());
  1080. aura::Window* menu_container =
  1081. CreateContainer(kShellWindowId_MenuContainer, "MenuContainer",
  1082. lock_screen_related_containers);
  1083. ::wm::SetChildWindowVisibilityChangesAnimated(menu_container);
  1084. menu_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1085. aura::Window* accessibility_bubble_container = CreateContainer(
  1086. kShellWindowId_AccessibilityBubbleContainer,
  1087. "AccessibilityBubbleContainer", lock_screen_related_containers);
  1088. accessibility_bubble_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
  1089. true);
  1090. aura::Window* drag_drop_container = CreateContainer(
  1091. kShellWindowId_DragImageAndTooltipContainer,
  1092. "DragImageAndTooltipContainer", lock_screen_related_containers);
  1093. ::wm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
  1094. drag_drop_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1095. aura::Window* overlay_container =
  1096. CreateContainer(kShellWindowId_OverlayContainer, "OverlayContainer",
  1097. lock_screen_related_containers);
  1098. overlay_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1099. overlay_container->SetLayoutManager(
  1100. new OverlayLayoutManager(overlay_container)); // Takes ownership.
  1101. if (chromeos::features::IsAmbientModeEnabled()) {
  1102. aura::Window* ambient_container =
  1103. CreateContainer(kShellWindowId_AmbientModeContainer,
  1104. "AmbientModeContainer", lock_screen_related_containers);
  1105. ::wm::SetChildWindowVisibilityChangesAnimated(ambient_container);
  1106. ambient_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1107. ambient_container->SetLayoutManager(
  1108. new FillLayoutManager(ambient_container)); // Takes ownership.
  1109. }
  1110. aura::Window* mouse_cursor_container =
  1111. CreateContainer(kShellWindowId_MouseCursorContainer,
  1112. "MouseCursorContainer", magnified_container);
  1113. mouse_cursor_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
  1114. aura::Window* always_on_top_wallpaper_container =
  1115. CreateContainer(kShellWindowId_AlwaysOnTopWallpaperContainer,
  1116. "AlwaysOnTopWallpaperContainer", magnified_container);
  1117. always_on_top_wallpaper_container->SetLayoutManager(
  1118. new FillLayoutManager(always_on_top_wallpaper_container));
  1119. CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
  1120. "PowerButtonAnimationContainer", magnified_container);
  1121. }
  1122. aura::Window* RootWindowController::CreateContainer(int window_id,
  1123. const char* name,
  1124. aura::Window* parent) {
  1125. aura::Window* window =
  1126. new aura::Window(nullptr, aura::client::WINDOW_TYPE_UNKNOWN);
  1127. window->Init(ui::LAYER_NOT_DRAWN);
  1128. window->SetId(window_id);
  1129. window->SetName(name);
  1130. parent->AddChild(window);
  1131. if (window_id != kShellWindowId_UnparentedContainer)
  1132. window->Show();
  1133. root_window_layout_manager_->AddContainer(window);
  1134. return window;
  1135. }
  1136. void RootWindowController::CreateSystemWallpaper(
  1137. RootWindowType root_window_type) {
  1138. SkColor color = SK_ColorBLACK;
  1139. // The splash screen appears on the primary display at boot. If this is a
  1140. // secondary monitor (either connected at boot or connected later) or if the
  1141. // browser restarted for a second login then don't use the boot color.
  1142. const bool is_boot_splash_screen =
  1143. root_window_type == RootWindowType::PRIMARY &&
  1144. base::CommandLine::ForCurrentProcess()->HasSwitch(
  1145. switches::kFirstExecAfterBoot);
  1146. if (is_boot_splash_screen)
  1147. color = kChromeOsBootColor;
  1148. system_wallpaper_ =
  1149. std::make_unique<SystemWallpaperController>(GetRootWindow(), color);
  1150. }
  1151. AccessibilityPanelLayoutManager*
  1152. RootWindowController::GetAccessibilityPanelLayoutManager() const {
  1153. aura::Window* container = const_cast<aura::Window*>(
  1154. GetContainer(kShellWindowId_AccessibilityPanelContainer));
  1155. auto* layout_manager = static_cast<AccessibilityPanelLayoutManager*>(
  1156. container->layout_manager());
  1157. return layout_manager;
  1158. }
  1159. void RootWindowController::OnMenuClosed() {
  1160. root_window_menu_model_adapter_.reset();
  1161. sort_apps_submenu_.reset();
  1162. shelf_->UpdateVisibilityState();
  1163. }
  1164. } // namespace ash