Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 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 | |
| 5 | #ifndef COMPONENTS_EXO_SHELL_SURFACE_BASE_H_ |
| 6 | #define COMPONENTS_EXO_SHELL_SURFACE_BASE_H_ |
| 7 | |
| 8 | #include <cstdint> |
| 9 | #include <memory> |
| 10 | #include <string> |
| 11 | |
| 12 | #include "ash/display/window_tree_host_manager.h" |
Mitsuru Oshima | 1143977 | 2017-12-14 02:06:59 | [diff] [blame] | 13 | #include "ash/public/interfaces/window_state_type.mojom.h" |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 14 | #include "base/macros.h" |
| 15 | #include "base/optional.h" |
| 16 | #include "base/strings/string16.h" |
| 17 | #include "components/exo/surface_observer.h" |
| 18 | #include "components/exo/surface_tree_host.h" |
Dominic Mazzoni | 336bc006 | 2018-09-23 16:46:43 | [diff] [blame] | 19 | #include "ui/accessibility/ax_tree_id.h" |
Mitsuru Oshima | a969732 | 2018-06-19 07:11:53 | [diff] [blame] | 20 | #include "ui/aura/client/capture_client_observer.h" |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 21 | #include "ui/aura/window_observer.h" |
| 22 | #include "ui/base/hit_test.h" |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 23 | #include "ui/display/display_observer.h" |
Dominik Laskowski | 4c265736 | 2018-09-05 00:35:09 | [diff] [blame] | 24 | #include "ui/display/types/display_constants.h" |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 25 | #include "ui/gfx/geometry/point.h" |
| 26 | #include "ui/gfx/geometry/rect.h" |
| 27 | #include "ui/gfx/geometry/vector2d.h" |
| 28 | #include "ui/views/widget/widget_delegate.h" |
| 29 | #include "ui/wm/public/activation_change_observer.h" |
| 30 | |
| 31 | namespace ash { |
Mitsuru Oshima | 1143977 | 2017-12-14 02:06:59 | [diff] [blame] | 32 | namespace wm { |
| 33 | class WindowState; |
| 34 | } |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 35 | } |
| 36 | |
| 37 | namespace base { |
| 38 | namespace trace_event { |
| 39 | class TracedValue; |
| 40 | } |
| 41 | } // namespace base |
| 42 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 43 | namespace exo { |
| 44 | class Surface; |
| 45 | |
| 46 | // This class provides functions for treating a surfaces like toplevel, |
| 47 | // fullscreen or popup widgets, move, resize or maximize them, associate |
| 48 | // metadata like title and class, etc. |
| 49 | class ShellSurfaceBase : public SurfaceTreeHost, |
| 50 | public SurfaceObserver, |
| 51 | public aura::WindowObserver, |
Mitsuru Oshima | a969732 | 2018-06-19 07:11:53 | [diff] [blame] | 52 | public aura::client::CaptureClientObserver, |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 53 | public views::WidgetDelegate, |
| 54 | public views::View, |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 55 | public wm::ActivationChangeObserver { |
| 56 | public: |
| 57 | // The |origin| is the initial position in screen coordinates. The position |
| 58 | // specified as part of the geometry is relative to the shell surface. |
| 59 | ShellSurfaceBase(Surface* surface, |
| 60 | const gfx::Point& origin, |
| 61 | bool activatable, |
| 62 | bool can_minimize, |
| 63 | int container); |
| 64 | ~ShellSurfaceBase() override; |
| 65 | |
| 66 | // Set the callback to run when the user wants the shell surface to be closed. |
| 67 | // The receiver can chose to not close the window on this signal. |
| 68 | void set_close_callback(const base::RepeatingClosure& close_callback) { |
| 69 | close_callback_ = close_callback; |
| 70 | } |
| 71 | |
| 72 | // Set the callback to run when the surface is destroyed. |
| 73 | void set_surface_destroyed_callback( |
| 74 | base::OnceClosure surface_destroyed_callback) { |
| 75 | surface_destroyed_callback_ = std::move(surface_destroyed_callback); |
| 76 | } |
| 77 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 78 | // Activates the shell surface. |
| 79 | void Activate(); |
| 80 | |
| 81 | // Set title for the surface. |
| 82 | void SetTitle(const base::string16& title); |
| 83 | |
| 84 | // Set icon for the surface. |
| 85 | void SetIcon(const gfx::ImageSkia& icon); |
| 86 | |
| 87 | // Sets the system modality. |
| 88 | void SetSystemModal(bool system_modal); |
| 89 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 90 | // Set the application ID for the surface. |
David Reveman | 8bc1641 | 2018-04-19 21:59:11 | [diff] [blame] | 91 | void SetApplicationId(const char* application_id); |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 92 | |
Tim Zheng | 08df566 | 2018-04-04 05:08:15 | [diff] [blame] | 93 | // Set the startup ID for the surface. |
| 94 | void SetStartupId(const char* startup_id); |
| 95 | |
Yuki Awano | b4514da | 2018-06-28 05:29:19 | [diff] [blame] | 96 | // Set the child ax tree ID for the surface. |
Dominic Mazzoni | 336bc006 | 2018-09-23 16:46:43 | [diff] [blame] | 97 | void SetChildAxTreeId(ui::AXTreeID child_ax_tree_id); |
Yuki Awano | b4514da | 2018-06-28 05:29:19 | [diff] [blame] | 98 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 99 | // Signal a request to close the window. It is up to the implementation to |
| 100 | // actually decide to do so though. |
| 101 | void Close(); |
| 102 | |
| 103 | // Set geometry for surface. The geometry represents the "visible bounds" |
| 104 | // for the surface from the user's perspective. |
| 105 | void SetGeometry(const gfx::Rect& geometry); |
| 106 | |
Dominik Laskowski | 4c265736 | 2018-09-05 00:35:09 | [diff] [blame] | 107 | // If set, geometry is in display rather than window or screen coordinates. |
| 108 | void SetDisplay(int64_t display_id); |
| 109 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 110 | // Set origin in screen coordinate space. |
| 111 | void SetOrigin(const gfx::Point& origin); |
| 112 | |
| 113 | // Set activatable state for surface. |
| 114 | void SetActivatable(bool activatable); |
| 115 | |
| 116 | // Set container for surface. |
| 117 | void SetContainer(int container); |
| 118 | |
| 119 | // Set the maximum size for the surface. |
| 120 | void SetMaximumSize(const gfx::Size& size); |
| 121 | |
| 122 | // Set the miniumum size for the surface. |
| 123 | void SetMinimumSize(const gfx::Size& size); |
| 124 | |
| 125 | void SetCanMinimize(bool can_minimize); |
| 126 | |
Mitsuru Oshima | 6288137 | 2018-02-06 01:45:04 | [diff] [blame] | 127 | // Prevents shell surface from being moved. |
| 128 | void DisableMovement(); |
| 129 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 130 | // Returns a trace value representing the state of the surface. |
| 131 | std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const; |
| 132 | |
| 133 | // Overridden from SurfaceDelegate: |
| 134 | void OnSurfaceCommit() override; |
Dominik Laskowski | 14a16377 | 2018-02-09 19:25:18 | [diff] [blame] | 135 | bool IsInputEnabled(Surface* surface) const override; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 136 | void OnSetFrame(SurfaceFrameType type) override; |
David Reveman | 786d318 | 2017-12-20 22:04:33 | [diff] [blame] | 137 | void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override; |
Tim Zheng | 08df566 | 2018-04-04 05:08:15 | [diff] [blame] | 138 | void OnSetStartupId(const char* startup_id) override; |
David Reveman | 21e2236d | 2018-04-12 06:01:10 | [diff] [blame] | 139 | void OnSetApplicationId(const char* application_id) override; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 140 | |
| 141 | // Overridden from SurfaceObserver: |
| 142 | void OnSurfaceDestroying(Surface* surface) override; |
| 143 | |
Mitsuru Oshima | a969732 | 2018-06-19 07:11:53 | [diff] [blame] | 144 | // Overridden from CaptureClientObserver: |
| 145 | void OnCaptureChanged(aura::Window* lost_capture, |
| 146 | aura::Window* gained_capture) override; |
| 147 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 148 | // Overridden from views::WidgetDelegate: |
| 149 | bool CanResize() const override; |
| 150 | bool CanMaximize() const override; |
| 151 | bool CanMinimize() const override; |
| 152 | base::string16 GetWindowTitle() const override; |
Evan Stade | 5052c19 | 2018-05-21 22:16:11 | [diff] [blame] | 153 | bool ShouldShowWindowTitle() const override; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 154 | gfx::ImageSkia GetWindowIcon() override; |
Dana Fried | 46c516e | 2018-12-17 23:00:52 | [diff] [blame^] | 155 | bool OnCloseRequested(views::Widget::ClosedReason close_reason) override; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 156 | void WindowClosing() override; |
| 157 | views::Widget* GetWidget() override; |
| 158 | const views::Widget* GetWidget() const override; |
| 159 | views::View* GetContentsView() override; |
| 160 | views::NonClientFrameView* CreateNonClientFrameView( |
| 161 | views::Widget* widget) override; |
| 162 | bool WidgetHasHitTestMask() const override; |
| 163 | void GetWidgetHitTestMask(gfx::Path* mask) const override; |
| 164 | |
| 165 | // Overridden from views::View: |
| 166 | gfx::Size CalculatePreferredSize() const override; |
| 167 | gfx::Size GetMinimumSize() const override; |
| 168 | gfx::Size GetMaximumSize() const override; |
Yuki Awano | b4514da | 2018-06-28 05:29:19 | [diff] [blame] | 169 | void GetAccessibleNodeData(ui::AXNodeData* node_data) override; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 170 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 171 | // Overridden from aura::WindowObserver: |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 172 | void OnWindowDestroying(aura::Window* window) override; |
| 173 | |
| 174 | // Overridden from wm::ActivationChangeObserver: |
| 175 | void OnWindowActivated(ActivationReason reason, |
| 176 | aura::Window* gained_active, |
| 177 | aura::Window* lost_active) override; |
| 178 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 179 | // Overridden from ui::AcceleratorTarget: |
| 180 | bool AcceleratorPressed(const ui::Accelerator& accelerator) override; |
| 181 | |
Mitsuru Oshima | 4eb127ce | 2018-07-09 23:53:39 | [diff] [blame] | 182 | bool frame_enabled() const { |
| 183 | return frame_type_ != SurfaceFrameType::NONE && |
| 184 | frame_type_ != SurfaceFrameType::SHADOW; |
| 185 | } |
| 186 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 187 | Surface* surface_for_testing() { return root_surface(); } |
| 188 | |
| 189 | protected: |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 190 | // Creates the |widget_| for |surface_|. |show_state| is the initial state |
| 191 | // of the widget (e.g. maximized). |
| 192 | void CreateShellSurfaceWidget(ui::WindowShowState show_state); |
| 193 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 194 | // Returns true if surface is currently being resized. |
| 195 | bool IsResizing() const; |
| 196 | |
| 197 | // Updates the bounds of widget to match the current surface bounds. |
| 198 | void UpdateWidgetBounds(); |
| 199 | |
| 200 | // Called by UpdateWidgetBounds to set widget bounds. |
Dominik Laskowski | 2398e74d | 2018-08-16 21:28:31 | [diff] [blame] | 201 | virtual void SetWidgetBounds(const gfx::Rect& bounds) = 0; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 202 | |
| 203 | // Updates the bounds of surface to match the current widget bounds. |
| 204 | void UpdateSurfaceBounds(); |
| 205 | |
| 206 | // Creates, deletes and update the shadow bounds based on |
| 207 | // |shadow_bounds_|. |
| 208 | void UpdateShadow(); |
| 209 | |
| 210 | // Applies |system_modal_| to |widget_|. |
| 211 | void UpdateSystemModal(); |
| 212 | |
| 213 | // Returns the "visible bounds" for the surface from the user's perspective. |
| 214 | gfx::Rect GetVisibleBounds() const; |
| 215 | |
Mitsuru Oshima | a969732 | 2018-06-19 07:11:53 | [diff] [blame] | 216 | // Returns the bounds of the client area.nnn |
| 217 | gfx::Rect GetClientViewBounds() const; |
| 218 | |
Dominik Laskowski | 2d431641 | 2017-12-13 19:14:44 | [diff] [blame] | 219 | // In the local coordinate system of the window. |
| 220 | virtual gfx::Rect GetShadowBounds() const; |
| 221 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 222 | // Set the parent window of this surface. |
| 223 | void SetParentWindow(aura::Window* parent); |
| 224 | |
Mitsuru Oshima | a969732 | 2018-06-19 07:11:53 | [diff] [blame] | 225 | // Start the event capture on this surface. |
| 226 | void StartCapture(); |
| 227 | |
Mitsuru Oshima | 014ad08 | 2018-03-30 22:36:06 | [diff] [blame] | 228 | const gfx::Rect& geometry() const { return geometry_; } |
| 229 | |
Mitsuru Oshima | 37a0eedb | 2018-09-14 20:42:21 | [diff] [blame] | 230 | // Install custom window targeter. Used to restore window targeter. |
| 231 | void InstallCustomWindowTargeter(); |
| 232 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 233 | views::Widget* widget_ = nullptr; |
| 234 | aura::Window* parent_ = nullptr; |
| 235 | bool movement_disabled_ = false; |
| 236 | gfx::Point origin_; |
| 237 | |
| 238 | // Container Window Id (see ash/public/cpp/shell_window_ids.h) |
| 239 | int container_; |
Jun Mukai | 17c449d | 2018-04-13 18:38:38 | [diff] [blame] | 240 | gfx::Rect geometry_; |
| 241 | gfx::Rect pending_geometry_; |
Dominik Laskowski | 4c265736 | 2018-09-05 00:35:09 | [diff] [blame] | 242 | int64_t display_id_ = display::kInvalidDisplayId; |
| 243 | int64_t pending_display_id_ = display::kInvalidDisplayId; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 244 | base::Optional<gfx::Rect> shadow_bounds_; |
| 245 | bool shadow_bounds_changed_ = false; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 246 | base::string16 title_; |
Mitsuru Oshima | 89e5c135 | 2018-01-17 07:29:39 | [diff] [blame] | 247 | // TODO(oshima): Remove this once the transition to new drag/resize |
| 248 | // complete. https://crbug.com/801666. |
| 249 | bool client_controlled_move_resize_ = true; |
Mitsuru Oshima | 8f00050 | 2018-04-07 23:11:50 | [diff] [blame] | 250 | SurfaceFrameType frame_type_ = SurfaceFrameType::NONE; |
Mitsuru Oshima | a969732 | 2018-06-19 07:11:53 | [diff] [blame] | 251 | bool is_popup_ = false; |
| 252 | bool has_grab_ = false; |
Mitsuru Oshima | 8f00050 | 2018-04-07 23:11:50 | [diff] [blame] | 253 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 254 | private: |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 255 | // Called on widget creation to initialize its window state. |
| 256 | // TODO(reveman): Remove virtual functions below to avoid FBC problem. |
| 257 | virtual void InitializeWindowState(ash::wm::WindowState* window_state) = 0; |
| 258 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 259 | // Returns the scale of the surface tree relative to the shell surface. |
| 260 | virtual float GetScale() const; |
| 261 | |
Mitsuru Oshima | 9f18560 | 2018-04-02 21:16:06 | [diff] [blame] | 262 | // Return the bounds of the widget/origin of surface taking visible |
| 263 | // bounds and current resize direction into account. |
Dominik Laskowski | 090ddbf | 2018-08-16 21:21:18 | [diff] [blame] | 264 | virtual base::Optional<gfx::Rect> GetWidgetBounds() const = 0; |
| 265 | virtual gfx::Point GetSurfaceOrigin() const = 0; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 266 | |
Dominik Laskowski | 4e71dae | 2018-08-25 04:12:45 | [diff] [blame] | 267 | // Commit is deferred if this returns false. |
| 268 | virtual bool OnPreWidgetCommit() = 0; |
Dominik Laskowski | 5b1287f | 2018-08-15 23:18:46 | [diff] [blame] | 269 | virtual void OnPostWidgetCommit() = 0; |
| 270 | |
| 271 | void CommitWidget(); |
| 272 | |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 273 | bool activatable_ = true; |
| 274 | bool can_minimize_ = true; |
David Reveman | 786d318 | 2017-12-20 22:04:33 | [diff] [blame] | 275 | bool has_frame_colors_ = false; |
| 276 | SkColor active_frame_color_ = SK_ColorBLACK; |
| 277 | SkColor inactive_frame_color_ = SK_ColorBLACK; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 278 | bool pending_show_widget_ = false; |
David Reveman | 8bc1641 | 2018-04-19 21:59:11 | [diff] [blame] | 279 | base::Optional<std::string> application_id_; |
| 280 | base::Optional<std::string> startup_id_; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 281 | base::RepeatingClosure close_callback_; |
| 282 | base::OnceClosure surface_destroyed_callback_; |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 283 | bool system_modal_ = false; |
| 284 | bool non_system_modal_window_was_active_ = false; |
| 285 | gfx::ImageSkia icon_; |
| 286 | gfx::Size minimum_size_; |
| 287 | gfx::Size pending_minimum_size_; |
| 288 | gfx::Size maximum_size_; |
| 289 | gfx::Size pending_maximum_size_; |
Dominic Mazzoni | 336bc006 | 2018-09-23 16:46:43 | [diff] [blame] | 290 | ui::AXTreeID child_ax_tree_id_ = ui::AXTreeIDUnknown(); |
Mitsuru Oshima | 3e16579 | 2017-12-11 22:27:48 | [diff] [blame] | 291 | |
| 292 | DISALLOW_COPY_AND_ASSIGN(ShellSurfaceBase); |
| 293 | }; |
| 294 | |
| 295 | } // namespace exo |
| 296 | |
| 297 | #endif // COMPONENTS_EXO_SHELL_SURFACE_BASE_H_ |