// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef ASH_ROOT_WINDOW_CONTROLLER_H_ #define ASH_ROOT_WINDOW_CONTROLLER_H_ #include #include #include #include "ash/ash_export.h" #include "ash/public/cpp/shelf_types.h" #include "ash/style/ash_color_provider_source.h" #include "ash/wm/workspace/workspace_types.h" #include "base/gtest_prod_util.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" namespace aura { class Window; } namespace gfx { class Point; } namespace ui { class WindowTreeHost; class SimpleMenuModel; } namespace views { class MenuRunner; class Widget; } // namespace views namespace wm { class ScopedCaptureClient; } namespace ash { class AccessibilityPanelLayoutManager; class AlwaysOnTopController; class AppMenuModelAdapter; class AshWindowTreeHost; class LockScreenActionBackgroundController; enum class LoginStatus; class RootWindowLayoutManager; class Shelf; class ShelfLayoutManager; class SplitViewController; class StackingController; class StatusAreaWidget; class SystemModalContainerLayoutManager; class SystemWallpaperController; class TouchExplorationManager; class TouchHudDebug; class TouchHudProjection; class WallpaperWidgetController; class WorkAreaInsets; // This class maintains the per root window state for ash. This class // owns the root window and other dependent objects that should be // deleted upon the deletion of the root window. This object is // indirectly owned and deleted by |WindowTreeHostManager|. // The RootWindowController for particular root window is stored in // its property (RootWindowSettings) and can be obtained using // |RootWindowController::ForWindow(aura::Window*)| function. class ASH_EXPORT RootWindowController { public: // Enumerates the type of display. If there is only a single display then // it is primary. In a multi-display environment one monitor is deemed the // PRIMARY and all others SECONDARY. enum class RootWindowType { PRIMARY, SECONDARY }; RootWindowController(const RootWindowController&) = delete; RootWindowController& operator=(const RootWindowController&) = delete; ~RootWindowController(); // Creates and Initialize the RootWindowController for primary display. // Returns a pointer to the newly created controller. static RootWindowController* CreateForPrimaryDisplay(AshWindowTreeHost* host); // Creates and Initialize the RootWindowController for secondary displays. // Returns a pointer to the newly created controller. static RootWindowController* CreateForSecondaryDisplay( AshWindowTreeHost* host); // Returns a RootWindowController of the window's root window. static RootWindowController* ForWindow(const aura::Window* window); // Returns the RootWindowController of the target root window. static RootWindowController* ForTargetRootWindow(); static std::vector root_window_controllers() { return root_window_controllers_ ? *root_window_controllers_ : std::vector(); } AshWindowTreeHost* ash_host() { return ash_host_.get(); } const AshWindowTreeHost* ash_host() const { return ash_host_.get(); } aura::WindowTreeHost* GetHost(); const aura::WindowTreeHost* GetHost() const; aura::Window* GetRootWindow(); const aura::Window* GetRootWindow() const; SplitViewController* split_view_controller() const { return split_view_controller_.get(); } Shelf* shelf() const { return shelf_.get(); } TouchHudDebug* touch_hud_debug() const { return touch_hud_debug_; } TouchHudProjection* touch_hud_projection() const { return touch_hud_projection_; } // Set touch HUDs for this root window controller. The root window controller // will not own the HUDs; their lifetimes are managed by themselves. Whenever // the widget showing a HUD is being destroyed (e.g. because of detaching a // display), the HUD deletes itself. void set_touch_hud_debug(TouchHudDebug* hud) { touch_hud_debug_ = hud; } void set_touch_hud_projection(TouchHudProjection* hud) { touch_hud_projection_ = hud; } RootWindowLayoutManager* root_window_layout_manager() { return root_window_layout_manager_; } // Returns parameters of the work area associated with this root window. WorkAreaInsets* work_area_insets() { return work_area_insets_.get(); } // Access the shelf layout manager associated with this root // window controller, NULL if no such shelf exists. ShelfLayoutManager* GetShelfLayoutManager(); // Returns the layout manager for the appropriate modal-container. If the // window is inside the lockscreen modal container, then the layout manager // for that is returned. Otherwise the layout manager for the default modal // container is returned. // If no window is specified (i.e. |window| is null), then the lockscreen // modal container is used if the screen is currently locked. Otherwise, the // default modal container is used. SystemModalContainerLayoutManager* GetSystemModalLayoutManager( aura::Window* window); AlwaysOnTopController* always_on_top_controller() { return always_on_top_controller_.get(); } // May return null, for example for a secondary monitor at the login screen. StatusAreaWidget* GetStatusAreaWidget(); // Returns if system tray and its widget is visible. bool IsSystemTrayVisible(); // True if the window can receive events on this root window. bool CanWindowReceiveEvents(aura::Window* window); // Returns the window events will be targeted at for the specified location // (in screen coordinates). // // NOTE: the returned window may not contain the location as resize handles // may extend outside the bounds of the window. aura::Window* FindEventTarget(const gfx::Point& location_in_screen); // Gets the last location seen in a mouse event in this root window's // coordinates. This may return a point outside the root window's bounds. gfx::Point GetLastMouseLocationInRoot(); aura::Window* GetContainer(int container_id); const aura::Window* GetContainer(int container_id) const; WallpaperWidgetController* wallpaper_widget_controller() { return wallpaper_widget_controller_.get(); } LockScreenActionBackgroundController* lock_screen_action_background_controller() { return lock_screen_action_background_controller_.get(); } AshColorProviderSource* color_provider_source() { return color_provider_source_.get(); } // Deletes associated objects and clears the state, but doesn't delete // the root window yet. This is used to delete a secondary displays' // root window safely when the display disconnect signal is received, // which may come while we're in the nested run loop. void Shutdown(); // Deletes all child windows and performs necessary cleanup. void CloseChildWindows(); // Moves child windows to |dest|. // TODO(afakhry): Consider renaming this function to avoid misuse. It is only // called by WindowTreeHostManager::DeleteHost(), and has destructive side // effects like deleting the workspace controllers, so it shouldn't be called // for something else. void MoveWindowsTo(aura::Window* dest); // Initialize touch HUDs if necessary. void InitTouchHuds(); // Returns the topmost window or one of its transient parents, if any of them // are in fullscreen mode. // TODO(afakhry): Rename this to imply getting the fullscreen window on the // currently active desk on this root. aura::Window* GetWindowForFullscreenMode(); // Returns true if window is fulllscreen and the shelf is hidden. bool IsInFullscreenMode(); // If touch exploration is enabled, update the touch exploration // controller so that synthesized touch events are anchored at this point. void SetTouchAccessibilityAnchorPoint(const gfx::Point& anchor_point); // Shows a context menu at the |location_in_screen|. void ShowContextMenu(const gfx::Point& location_in_screen, ui::MenuSourceType source_type); void HideContextMenu(); void HideContextMenuNoAnimation(); bool IsContextMenuShown() const; // Called when the login status changes after login (such as lock/unlock). void UpdateAfterLoginStatusChange(LoginStatus status); void CreateAmbientWidget(); void CloseAmbientWidget(bool immediately); bool HasAmbientWidget() const; views::Widget* ambient_widget_for_testing() { return ambient_widget_.get(); } AppMenuModelAdapter* menu_model_adapter_for_testing() { return root_window_menu_model_adapter_.get(); } // Returns accessibility panel layout manager for this root window. AccessibilityPanelLayoutManager* GetAccessibilityPanelLayoutManagerForTest(); private: FRIEND_TEST_ALL_PREFIXES(RootWindowControllerTest, ContextMenuDisappearsInTabletMode); // Takes ownership of |ash_host|. explicit RootWindowController(AshWindowTreeHost* ash_host); // Initializes the RootWindowController based on |root_window_type|. void Init(RootWindowType root_window_type); void InitLayoutManagers(); AccessibilityPanelLayoutManager* GetAccessibilityPanelLayoutManager() const; // Creates the containers (aura::Windows) used by the shell. void CreateContainers(); // Creates a new window for use as a container. aura::Window* CreateContainer(int window_id, const char* name, aura::Window* parent); // Initializes |system_wallpaper_| and possibly also |boot_splash_screen_|. // The initial color is determined by the |root_window_type| and whether or // not this is the first boot. void CreateSystemWallpaper(RootWindowType root_window_type); // Callback for MenuRunner. void OnMenuClosed(); // Passed as callback to |wallpaper_widget_controller_| - run when the // wallpaper widget is first set. void OnFirstWallpaperWidgetSet(); std::unique_ptr ash_host_; // |ash_host_| as a WindowTreeHost. aura::WindowTreeHost* window_tree_host_; // LayoutManagers are owned by the window they are installed on. RootWindowLayoutManager* root_window_layout_manager_ = nullptr; std::unique_ptr wallpaper_widget_controller_; std::unique_ptr always_on_top_controller_; // Manages the context menu. std::unique_ptr root_window_menu_model_adapter_; std::unique_ptr sort_apps_submenu_; std::unique_ptr stacking_controller_; std::unique_ptr split_view_controller_; // The shelf controller for this root window. Exists for the entire lifetime // of the RootWindowController so that it is safe for observers to be added // to it during construction of the shelf widget and status tray. std::unique_ptr shelf_; std::unique_ptr system_wallpaper_; // Responsible for initializing TouchExplorationController when spoken // feedback is on. std::unique_ptr touch_exploration_manager_; // Heads-up displays for touch events. These HUDs are not owned by the root // window controller and manage their own lifetimes. TouchHudDebug* touch_hud_debug_ = nullptr; TouchHudProjection* touch_hud_projection_ = nullptr; std::unique_ptr<::wm::ScopedCaptureClient> capture_client_; std::unique_ptr lock_screen_action_background_controller_; std::unique_ptr ambient_widget_; std::unique_ptr color_provider_source_; // Whether child windows have been closed during shutdown. Exists to avoid // calling related cleanup code more than once. bool did_close_child_windows_ = false; std::unique_ptr work_area_insets_; static std::vector* root_window_controllers_; }; } // namespace ash #endif // ASH_ROOT_WINDOW_CONTROLLER_H_