shell_surface_base.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. // Copyright 2015 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. #ifndef COMPONENTS_EXO_SHELL_SURFACE_BASE_H_
  5. #define COMPONENTS_EXO_SHELL_SURFACE_BASE_H_
  6. #include <cstdint>
  7. #include <memory>
  8. #include <string>
  9. #include "ash/display/window_tree_host_manager.h"
  10. #include "base/gtest_prod_util.h"
  11. #include "chromeos/ui/base/display_util.h"
  12. #include "chromeos/ui/base/window_pin_type.h"
  13. #include "components/exo/surface_observer.h"
  14. #include "components/exo/surface_tree_host.h"
  15. #include "third_party/abseil-cpp/absl/types/optional.h"
  16. #include "ui/accessibility/ax_tree_id.h"
  17. #include "ui/aura/client/capture_client_observer.h"
  18. #include "ui/aura/window_observer.h"
  19. #include "ui/base/hit_test.h"
  20. #include "ui/display/display_observer.h"
  21. #include "ui/display/types/display_constants.h"
  22. #include "ui/gfx/geometry/point.h"
  23. #include "ui/gfx/geometry/rect.h"
  24. #include "ui/gfx/geometry/vector2d.h"
  25. #include "ui/views/widget/widget_delegate.h"
  26. #include "ui/views/widget/widget_observer.h"
  27. #include "ui/wm/public/activation_change_observer.h"
  28. namespace ash {
  29. class WindowState;
  30. } // namespace ash
  31. namespace base {
  32. namespace trace_event {
  33. class TracedValue;
  34. }
  35. } // namespace base
  36. namespace exo {
  37. class Surface;
  38. // This class provides functions for treating a surfaces like toplevel,
  39. // fullscreen or popup widgets, move, resize or maximize them, associate
  40. // metadata like title and class, etc.
  41. class ShellSurfaceBase : public SurfaceTreeHost,
  42. public SurfaceObserver,
  43. public aura::WindowObserver,
  44. public aura::client::CaptureClientObserver,
  45. public views::WidgetDelegate,
  46. public views::WidgetObserver,
  47. public views::View,
  48. public wm::ActivationChangeObserver {
  49. public:
  50. // The |origin| is the initial position in screen coordinates. The position
  51. // specified as part of the geometry is relative to the shell surface.
  52. ShellSurfaceBase(Surface* surface,
  53. const gfx::Point& origin,
  54. bool can_minimize,
  55. int container);
  56. ShellSurfaceBase(const ShellSurfaceBase&) = delete;
  57. ShellSurfaceBase& operator=(const ShellSurfaceBase&) = delete;
  58. ~ShellSurfaceBase() override;
  59. // Set the callback to run when the user wants the shell surface to be closed.
  60. // The receiver can chose to not close the window on this signal.
  61. void set_close_callback(const base::RepeatingClosure& close_callback) {
  62. close_callback_ = close_callback;
  63. }
  64. // Set the callback to run when the user has requested to close the surface.
  65. // This runs before the normal |close_callback_| and should not be used to
  66. // actually close the surface.
  67. void set_pre_close_callback(const base::RepeatingClosure& close_callback) {
  68. pre_close_callback_ = close_callback;
  69. }
  70. // Set the callback to run when the surface is destroyed.
  71. void set_surface_destroyed_callback(
  72. base::OnceClosure surface_destroyed_callback) {
  73. surface_destroyed_callback_ = std::move(surface_destroyed_callback);
  74. }
  75. // Whether the connected client supports setting window bounds and is
  76. // expecting to receive window origin in configure updates.
  77. bool client_supports_window_bounds() const {
  78. return client_supports_window_bounds_;
  79. }
  80. void set_client_supports_window_bounds(bool enable) {
  81. client_supports_window_bounds_ = enable;
  82. }
  83. // Activates the shell surface.
  84. void Activate();
  85. // Set title for the surface.
  86. void SetTitle(const std::u16string& title);
  87. // Set icon for the surface.
  88. void SetIcon(const gfx::ImageSkia& icon);
  89. // Set the application ID for the surface.
  90. void SetApplicationId(const char* application_id);
  91. // Set the startup ID for the surface.
  92. void SetStartupId(const char* startup_id);
  93. // Set the child ax tree ID for the surface.
  94. void SetChildAxTreeId(ui::AXTreeID child_ax_tree_id);
  95. // Set geometry for surface. The geometry represents the "visible bounds"
  96. // for the surface from the user's perspective.
  97. void SetGeometry(const gfx::Rect& geometry);
  98. // If set, geometry is in display rather than window or screen coordinates.
  99. void SetDisplay(int64_t display_id);
  100. // Set origin in screen coordinate space.
  101. void SetOrigin(const gfx::Point& origin);
  102. // Set activatable state for surface.
  103. void SetActivatable(bool activatable);
  104. // Set container for surface.
  105. void SetContainer(int container);
  106. // Set the maximum size for the surface.
  107. void SetMaximumSize(const gfx::Size& size);
  108. // Set the miniumum size for the surface.
  109. void SetMinimumSize(const gfx::Size& size);
  110. // Set the flag if the surface can maximize or not.
  111. void SetCanMinimize(bool can_minimize);
  112. // Set normal shadow bounds, |shadow_bounds_|, to |bounds| to be used and
  113. // applied via `UpdateShadow()`. Set and update resize shadow bounds with
  114. // |widget_|'s origin and |bounds| via `UpdateResizeShadowBoundsOfWindow()`.
  115. void SetBoundsForShadows(const absl::optional<gfx::Rect>& bounds);
  116. // Make the shell surface menu type.
  117. void SetMenu();
  118. // Prevents shell surface from being moved.
  119. void DisableMovement();
  120. // Update the resizability for the surface.
  121. virtual void UpdateResizability();
  122. // Rebind a surface as the root surface of the shell surface.
  123. void RebindRootSurface(Surface* root_surface,
  124. bool can_minimize,
  125. int container);
  126. // Set the window bounds. The bounds specify 'visible bounds' of the
  127. // shell surface.
  128. void SetWindowBounds(const gfx::Rect& bounds_in_screen);
  129. // Set `restore_session_id_` and `restore_window_id_` to be the browser
  130. // session id and restore id, respectively.
  131. void SetRestoreInfo(int32_t restore_id, int32_t restore_window_id);
  132. // Set `restore_window_id_source` to be the app id for Restore to fetch window
  133. // id for.
  134. void SetRestoreInfoWithWindowIdSource(
  135. int32_t restore_id,
  136. const std::string& restore_window_id_source);
  137. // Floats (place on top of other surfaces) or unfloats the shell surface.
  138. void SetFloat();
  139. void UnsetFloat();
  140. // Returns a trace value representing the state of the surface.
  141. std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
  142. // An overlay creation parameters. The view is owned by the
  143. // overlay.
  144. struct OverlayParams {
  145. OverlayParams(std::unique_ptr<views::View> overlay);
  146. ~OverlayParams();
  147. bool translucent = false;
  148. bool overlaps_frame = true;
  149. absl::optional<bool> can_resize;
  150. // TODO(oshima): It's unlikely for overlay not to request focus.
  151. // Remove this.
  152. bool focusable = true;
  153. std::unique_ptr<views::View> contents_view;
  154. };
  155. // Add a new overlay. Currently only one overlay is supported.
  156. // It is caller's responsibility to make sure there is no overlay
  157. // before calling this.
  158. void AddOverlay(OverlayParams&& params);
  159. // Remove the current overlay. This is no-op if there is no overlay.
  160. void RemoveOverlay();
  161. bool HasOverlay() const { return !!overlay_widget_; }
  162. // Set specific orientation lock for this surface. When this surface is in
  163. // foreground and the display can be rotated (e.g. tablet mode), apply the
  164. // behavior defined by |orientation_lock|. See more details in
  165. // //ash/display/screen_orientation_controller.h.
  166. void SetOrientationLock(chromeos::OrientationType orientation_lock);
  167. // Sets the z order for the window. If the window's widget has not yet been
  168. // initialized, it saves `z_order` for when it is initialized.
  169. void SetZOrder(ui::ZOrderLevel z_order);
  170. // SurfaceDelegate:
  171. void OnSurfaceCommit() override;
  172. bool IsInputEnabled(Surface* surface) const override;
  173. void OnSetFrame(SurfaceFrameType type) override;
  174. void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override;
  175. void OnSetStartupId(const char* startup_id) override;
  176. void OnSetApplicationId(const char* application_id) override;
  177. void SetUseImmersiveForFullscreen(bool value) override;
  178. void ShowSnapPreviewToPrimary() override;
  179. void ShowSnapPreviewToSecondary() override;
  180. void HideSnapPreview() override;
  181. void SetSnappedToPrimary() override;
  182. void SetSnappedToSecondary() override;
  183. void UnsetSnap() override;
  184. void OnActivationRequested() override;
  185. void OnSetServerStartResize() override;
  186. void SetCanGoBack() override;
  187. void UnsetCanGoBack() override;
  188. void SetPip() override;
  189. void UnsetPip() override;
  190. void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
  191. void MoveToDesk(int desk_index) override;
  192. void SetVisibleOnAllWorkspaces() override;
  193. void SetInitialWorkspace(const char* initial_workspace) override;
  194. void Pin(bool trusted) override;
  195. void Unpin() override;
  196. void SetSystemModal(bool system_modal) override;
  197. // SurfaceObserver:
  198. void OnSurfaceDestroying(Surface* surface) override;
  199. void OnContentSizeChanged(Surface*) override {}
  200. void OnFrameLockingChanged(Surface*, bool) override {}
  201. void OnDeskChanged(Surface*, int) override {}
  202. // CaptureClientObserver:
  203. void OnCaptureChanged(aura::Window* lost_capture,
  204. aura::Window* gained_capture) override;
  205. // views::WidgetDelegate:
  206. bool OnCloseRequested(views::Widget::ClosedReason close_reason) override;
  207. void WindowClosing() override;
  208. views::Widget* GetWidget() override;
  209. const views::Widget* GetWidget() const override;
  210. views::View* GetContentsView() override;
  211. std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
  212. views::Widget* widget) override;
  213. bool ShouldSaveWindowPlacement() const override;
  214. bool WidgetHasHitTestMask() const override;
  215. void GetWidgetHitTestMask(SkPath* mask) const override;
  216. // views::WidgetObserver:
  217. void OnWidgetClosing(views::Widget* widget) override;
  218. // views::View:
  219. gfx::Size CalculatePreferredSize() const override;
  220. // This returns the surface's min/max size. If you want to know the
  221. // widget/window's min/mx size, you must use
  222. // ShellSurfaceBase::GetWidget()->GetXxxSize.
  223. gfx::Size GetMinimumSize() const override;
  224. gfx::Size GetMaximumSize() const override;
  225. void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
  226. views::FocusTraversable* GetFocusTraversable() override;
  227. // aura::WindowObserver:
  228. void OnWindowDestroying(aura::Window* window) override;
  229. void OnWindowPropertyChanged(aura::Window* window,
  230. const void* key,
  231. intptr_t old_value) override;
  232. void OnWindowAddedToRootWindow(aura::Window* window) override;
  233. void OnWindowParentChanged(aura::Window* window,
  234. aura::Window* parent) override;
  235. // wm::ActivationChangeObserver:
  236. void OnWindowActivated(ActivationReason reason,
  237. aura::Window* gained_active,
  238. aura::Window* lost_active) override;
  239. // ui::AcceleratorTarget:
  240. bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
  241. bool frame_enabled() const {
  242. return frame_type_ != SurfaceFrameType::NONE &&
  243. frame_type_ != SurfaceFrameType::SHADOW;
  244. }
  245. Surface* surface_for_testing() { return root_surface(); }
  246. bool get_shadow_bounds_changed_for_testing() {
  247. return shadow_bounds_changed_;
  248. }
  249. bool server_side_resize() const { return server_side_resize_; }
  250. const views::Widget* overlay_widget_for_testing() const {
  251. return overlay_widget_.get();
  252. }
  253. // Returns true if surface is currently being dragged.
  254. bool IsDragged() const;
  255. void set_in_extended_drag(bool in_extended_drag) {
  256. in_extended_drag_ = in_extended_drag;
  257. }
  258. protected:
  259. // Creates the |widget_| for |surface_|. |show_state| is the initial state
  260. // of the widget (e.g. maximized).
  261. void CreateShellSurfaceWidget(ui::WindowShowState show_state);
  262. // Lets subclasses modify Widget parameters immediately before widget
  263. // creation.
  264. virtual void OverrideInitParams(views::Widget::InitParams* params) {}
  265. // Returns true if surface is currently being resized.
  266. bool IsResizing() const;
  267. // Updates the bounds of widget to match the current surface bounds.
  268. void UpdateWidgetBounds();
  269. // Returns a bounds that WindowManager might have applied the constraints to.
  270. virtual gfx::Rect ComputeAdjustedBounds(const gfx::Rect& bounds) const;
  271. // Called by UpdateWidgetBounds to set widget bounds. If the
  272. // `adjusted_by_server` is true, the bounds requested by a client is updated
  273. // to satisfy the constraints.
  274. virtual void SetWidgetBounds(const gfx::Rect& bounds,
  275. bool adjusted_by_server) = 0;
  276. // Updates the bounds of surface to match the current widget bounds.
  277. void UpdateSurfaceBounds();
  278. // Creates, deletes and update the shadow bounds based on
  279. // |shadow_bounds_|.
  280. void UpdateShadow();
  281. // Updates the corner radius depending on whether the |widget_| is in pip or
  282. // not.
  283. void UpdateCornerRadius();
  284. virtual void UpdateFrameType();
  285. // Applies |system_modal_| to |widget_|.
  286. void UpdateSystemModal();
  287. // Returns the "visible bounds" for the surface from the user's perspective.
  288. gfx::Rect GetVisibleBounds() const;
  289. // Returns the bounds of the client area.
  290. gfx::Rect GetClientViewBounds() const;
  291. // Computes the widget bounds using visible bounds.
  292. gfx::Rect GetWidgetBoundsFromVisibleBounds() const;
  293. // In the local coordinate system of the window.
  294. virtual gfx::Rect GetShadowBounds() const;
  295. // Start the event capture on this surface.
  296. void StartCapture();
  297. const gfx::Rect& geometry() const { return geometry_; }
  298. aura::Window* parent() const { return parent_; }
  299. // Install custom window targeter. Used to restore window targeter.
  300. void InstallCustomWindowTargeter();
  301. // Creates a NonClientFrameView for shell surface.
  302. std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameViewInternal(
  303. views::Widget* widget);
  304. virtual void OnPostWidgetCommit();
  305. void SetParentInternal(aura::Window* window);
  306. void SetContainerInternal(int container);
  307. // Converts min/max sizes to resizeability. This needs to be overridden as
  308. // different clients have different default min/max values.
  309. virtual bool GetCanResizeFromSizeConstraints() const = 0;
  310. // Returns true if this surface will exit fullscreen from a restore or
  311. // maximize request. Currently only true for Lacros.
  312. bool ShouldExitFullscreenFromRestoreOrMaximized();
  313. views::Widget* widget_ = nullptr;
  314. bool movement_disabled_ = false;
  315. gfx::Point origin_;
  316. // Container Window Id (see ash/public/cpp/shell_window_ids.h)
  317. int container_;
  318. gfx::Rect geometry_;
  319. gfx::Rect pending_geometry_;
  320. absl::optional<gfx::Rect> initial_bounds_;
  321. int64_t display_id_ = display::kInvalidDisplayId;
  322. int64_t pending_display_id_ = display::kInvalidDisplayId;
  323. absl::optional<gfx::Rect> shadow_bounds_;
  324. bool shadow_bounds_changed_ = false;
  325. SurfaceFrameType frame_type_ = SurfaceFrameType::NONE;
  326. bool is_popup_ = false;
  327. bool is_menu_ = false;
  328. bool has_grab_ = false;
  329. bool server_side_resize_ = false;
  330. bool needs_layout_on_show_ = false;
  331. bool client_supports_window_bounds_ = false;
  332. gfx::Size minimum_size_;
  333. gfx::Size maximum_size_;
  334. // The orientation to be applied when widget is being created. Only set when
  335. // widget is not created yet orientation lock is being set. This is currently
  336. // only used by ClientControlledShellSurface.
  337. chromeos::OrientationType initial_orientation_lock_ =
  338. chromeos::OrientationType::kAny;
  339. private:
  340. FRIEND_TEST_ALL_PREFIXES(ShellSurfaceTest,
  341. HostWindowBoundsUpdatedAfterCommitWidget);
  342. // Called on widget creation to initialize its window state.
  343. // TODO(reveman): Remove virtual functions below to avoid FBC problem.
  344. virtual void InitializeWindowState(ash::WindowState* window_state) = 0;
  345. // Returns the scale of the surface tree relative to the shell surface.
  346. virtual float GetScale() const;
  347. // Return the bounds of the widget/origin of surface taking visible
  348. // bounds and current resize direction into account.
  349. virtual absl::optional<gfx::Rect> GetWidgetBounds() const = 0;
  350. virtual gfx::Point GetSurfaceOrigin() const = 0;
  351. // Commit is deferred if this returns false.
  352. virtual bool OnPreWidgetCommit() = 0;
  353. void CommitWidget();
  354. bool IsFrameDecorationSupported(SurfaceFrameType frame_type);
  355. void UpdatePinned();
  356. // Returns the resizability of the window. Useful to get the resizability
  357. // without actually updating it.
  358. bool CalculateCanResize() const;
  359. aura::Window* parent_ = nullptr;
  360. bool activatable_ = true;
  361. bool can_minimize_ = true;
  362. bool has_frame_colors_ = false;
  363. SkColor active_frame_color_ = SK_ColorBLACK;
  364. SkColor inactive_frame_color_ = SK_ColorBLACK;
  365. bool pending_show_widget_ = false;
  366. absl::optional<std::string> application_id_;
  367. absl::optional<std::string> startup_id_;
  368. bool immersive_implied_by_fullscreen_ = true;
  369. base::RepeatingClosure close_callback_;
  370. base::RepeatingClosure pre_close_callback_;
  371. base::OnceClosure surface_destroyed_callback_;
  372. bool system_modal_ = false;
  373. bool non_system_modal_window_was_active_ = false;
  374. gfx::Size pending_minimum_size_;
  375. gfx::Size pending_maximum_size_;
  376. gfx::SizeF pending_aspect_ratio_;
  377. bool pending_pip_ = false;
  378. bool in_extended_drag_ = false;
  379. absl::optional<std::string> initial_workspace_;
  380. absl::optional<ui::ZOrderLevel> initial_z_order_;
  381. // Restore members. These pass window restore related ids from exo clients,
  382. // e.g. Lacros, so that the window can be created with the correct restore
  383. // info looked up using the ids.
  384. absl::optional<int32_t> restore_session_id_;
  385. absl::optional<int32_t> restore_window_id_;
  386. absl::optional<std::string> restore_window_id_source_;
  387. // Overlay members.
  388. std::unique_ptr<views::Widget> overlay_widget_;
  389. bool skip_ime_processing_ = false;
  390. bool overlay_overlaps_frame_ = true;
  391. absl::optional<bool> overlay_can_resize_;
  392. // Pin members.
  393. chromeos::WindowPinType current_pinned_state_ =
  394. chromeos::WindowPinType::kNone;
  395. chromeos::WindowPinType pending_pinned_state_ =
  396. chromeos::WindowPinType::kNone;
  397. };
  398. } // namespace exo
  399. #endif // COMPONENTS_EXO_SHELL_SURFACE_BASE_H_