blob: dd3b05be00df41fbf565ff0d5c9b20f3bb0a4dac [file] [log] [blame]
Mitsuru Oshima3e165792017-12-11 22:27:481// 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 Oshima11439772017-12-14 02:06:5913#include "ash/public/interfaces/window_state_type.mojom.h"
Mitsuru Oshima3e165792017-12-11 22:27:4814#include "base/containers/circular_deque.h"
15#include "base/macros.h"
16#include "base/optional.h"
17#include "base/strings/string16.h"
18#include "components/exo/surface_observer.h"
19#include "components/exo/surface_tree_host.h"
Mitsuru Oshima3e165792017-12-11 22:27:4820#include "ui/aura/window_observer.h"
21#include "ui/base/hit_test.h"
22#include "ui/compositor/compositor_lock.h"
23#include "ui/display/display_observer.h"
24#include "ui/gfx/geometry/point.h"
25#include "ui/gfx/geometry/rect.h"
26#include "ui/gfx/geometry/vector2d.h"
27#include "ui/views/widget/widget_delegate.h"
28#include "ui/wm/public/activation_change_observer.h"
29
30namespace ash {
31class WindowResizer;
Mitsuru Oshima11439772017-12-14 02:06:5932namespace wm {
33class WindowState;
34}
Mitsuru Oshima3e165792017-12-11 22:27:4835}
36
37namespace base {
38namespace trace_event {
39class TracedValue;
40}
41} // namespace base
42
43namespace ui {
44class CompositorLock;
45} // namespace ui
46
47namespace exo {
48class Surface;
49
50// This class provides functions for treating a surfaces like toplevel,
51// fullscreen or popup widgets, move, resize or maximize them, associate
52// metadata like title and class, etc.
53class ShellSurfaceBase : public SurfaceTreeHost,
54 public SurfaceObserver,
55 public aura::WindowObserver,
56 public views::WidgetDelegate,
57 public views::View,
Mitsuru Oshima3e165792017-12-11 22:27:4858 public wm::ActivationChangeObserver {
59 public:
60 // The |origin| is the initial position in screen coordinates. The position
61 // specified as part of the geometry is relative to the shell surface.
62 ShellSurfaceBase(Surface* surface,
63 const gfx::Point& origin,
64 bool activatable,
65 bool can_minimize,
66 int container);
67 ~ShellSurfaceBase() override;
68
69 // Set the callback to run when the user wants the shell surface to be closed.
70 // The receiver can chose to not close the window on this signal.
71 void set_close_callback(const base::RepeatingClosure& close_callback) {
72 close_callback_ = close_callback;
73 }
74
75 // Set the callback to run when the surface is destroyed.
76 void set_surface_destroyed_callback(
77 base::OnceClosure surface_destroyed_callback) {
78 surface_destroyed_callback_ = std::move(surface_destroyed_callback);
79 }
80
Mitsuru Oshima3e165792017-12-11 22:27:4881 // Set the callback to run when the client is asked to configure the surface.
82 // The size is a hint, in the sense that the client is free to ignore it if
83 // it doesn't resize, pick a smaller size (to satisfy aspect ratio or resize
84 // in steps of NxM pixels).
85 using ConfigureCallback =
86 base::RepeatingCallback<uint32_t(const gfx::Size& size,
87 ash::mojom::WindowStateType state_type,
88 bool resizing,
89 bool activated,
90 const gfx::Vector2d& origin_offset)>;
91 void set_configure_callback(const ConfigureCallback& configure_callback) {
92 configure_callback_ = configure_callback;
93 }
94
95 // When the client is asked to configure the surface, it should acknowledge
96 // the configure request sometime before the commit. |serial| is the serial
97 // from the configure callback.
98 void AcknowledgeConfigure(uint32_t serial);
99
100 // Activates the shell surface.
101 void Activate();
102
103 // Set title for the surface.
104 void SetTitle(const base::string16& title);
105
106 // Set icon for the surface.
107 void SetIcon(const gfx::ImageSkia& icon);
108
109 // Sets the system modality.
110 void SetSystemModal(bool system_modal);
111
112 // Start an interactive move of surface.
Mitsuru Oshima89e5c1352018-01-17 07:29:39113 // TODO(oshima): Move this to ShellSurface.
Mitsuru Oshima3e165792017-12-11 22:27:48114 void Move();
115
116 // Sets the application ID for the window. The application ID identifies the
117 // general class of applications to which the window belongs.
118 static void SetApplicationId(aura::Window* window, const std::string& id);
119 static const std::string* GetApplicationId(aura::Window* window);
120
121 // Set the application ID for the surface.
122 void SetApplicationId(const std::string& application_id);
123
124 // Signal a request to close the window. It is up to the implementation to
125 // actually decide to do so though.
126 void Close();
127
128 // Set geometry for surface. The geometry represents the "visible bounds"
129 // for the surface from the user's perspective.
130 void SetGeometry(const gfx::Rect& geometry);
131
132 // Set origin in screen coordinate space.
133 void SetOrigin(const gfx::Point& origin);
134
135 // Set activatable state for surface.
136 void SetActivatable(bool activatable);
137
138 // Set container for surface.
139 void SetContainer(int container);
140
141 // Set the maximum size for the surface.
142 void SetMaximumSize(const gfx::Size& size);
143
144 // Set the miniumum size for the surface.
145 void SetMinimumSize(const gfx::Size& size);
146
147 void SetCanMinimize(bool can_minimize);
148
Mitsuru Oshima62881372018-02-06 01:45:04149 // Prevents shell surface from being moved.
150 void DisableMovement();
151
Mitsuru Oshima3e165792017-12-11 22:27:48152 // Sets the main surface for the window.
153 static void SetMainSurface(aura::Window* window, Surface* surface);
154
155 // Returns the main Surface instance or nullptr if it is not set.
156 // |window| must not be nullptr.
157 static Surface* GetMainSurface(const aura::Window* window);
158
159 // Returns a trace value representing the state of the surface.
160 std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
161
162 // Overridden from SurfaceDelegate:
163 void OnSurfaceCommit() override;
Dominik Laskowski14a163772018-02-09 19:25:18164 bool IsInputEnabled(Surface* surface) const override;
Mitsuru Oshima3e165792017-12-11 22:27:48165 void OnSetFrame(SurfaceFrameType type) override;
David Reveman786d3182017-12-20 22:04:33166 void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override;
Mitsuru Oshima3e165792017-12-11 22:27:48167 void OnSetParent(Surface* parent, const gfx::Point& position) override;
168
169 // Overridden from SurfaceObserver:
170 void OnSurfaceDestroying(Surface* surface) override;
171
172 // Overridden from views::WidgetDelegate:
173 bool CanResize() const override;
174 bool CanMaximize() const override;
175 bool CanMinimize() const override;
176 base::string16 GetWindowTitle() const override;
177 gfx::ImageSkia GetWindowIcon() override;
178 void WindowClosing() override;
179 views::Widget* GetWidget() override;
180 const views::Widget* GetWidget() const override;
181 views::View* GetContentsView() override;
182 views::NonClientFrameView* CreateNonClientFrameView(
183 views::Widget* widget) override;
184 bool WidgetHasHitTestMask() const override;
185 void GetWidgetHitTestMask(gfx::Path* mask) const override;
186
187 // Overridden from views::View:
188 gfx::Size CalculatePreferredSize() const override;
189 gfx::Size GetMinimumSize() const override;
190 gfx::Size GetMaximumSize() const override;
191
Mitsuru Oshima3e165792017-12-11 22:27:48192 // Overridden from aura::WindowObserver:
193 void OnWindowBoundsChanged(aura::Window* window,
194 const gfx::Rect& old_bounds,
195 const gfx::Rect& new_bounds,
196 ui::PropertyChangeReason reason) override;
197 void OnWindowDestroying(aura::Window* window) override;
198
199 // Overridden from wm::ActivationChangeObserver:
200 void OnWindowActivated(ActivationReason reason,
201 aura::Window* gained_active,
202 aura::Window* lost_active) override;
203
204 // Overridden from ui::EventHandler:
205 void OnKeyEvent(ui::KeyEvent* event) override;
206 void OnMouseEvent(ui::MouseEvent* event) override;
207 void OnGestureEvent(ui::GestureEvent* event) override;
208
209 // Overridden from ui::AcceleratorTarget:
210 bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
211
212 Surface* surface_for_testing() { return root_surface(); }
213
214 protected:
215 // Helper class used to coalesce a number of changes into one "configure"
216 // callback. Callbacks are suppressed while an instance of this class is
217 // instantiated and instead called when the instance is destroyed.
218 // If |force_configure_| is true ShellSurfaceBase::Configure() will be called
219 // even if no changes to shell surface took place during the lifetime of the
220 // ScopedConfigure instance.
221 class ScopedConfigure {
222 public:
223 ScopedConfigure(ShellSurfaceBase* shell_surface, bool force_configure);
224 ~ScopedConfigure();
225
226 void set_needs_configure() { needs_configure_ = true; }
227
228 private:
229 ShellSurfaceBase* const shell_surface_;
230 const bool force_configure_;
231 bool needs_configure_ = false;
232
233 DISALLOW_COPY_AND_ASSIGN(ScopedConfigure);
234 };
235
236 // Creates the |widget_| for |surface_|. |show_state| is the initial state
237 // of the widget (e.g. maximized).
238 void CreateShellSurfaceWidget(ui::WindowShowState show_state);
239
240 // Asks the client to configure its surface.
241 void Configure();
242
243 // Returns true if surface is currently being resized.
244 bool IsResizing() const;
245
246 // Updates the bounds of widget to match the current surface bounds.
247 void UpdateWidgetBounds();
248
249 // Called by UpdateWidgetBounds to set widget bounds.
250 virtual void SetWidgetBounds(const gfx::Rect& bounds);
251
252 // Updates the bounds of surface to match the current widget bounds.
253 void UpdateSurfaceBounds();
254
255 // Creates, deletes and update the shadow bounds based on
256 // |shadow_bounds_|.
257 void UpdateShadow();
258
259 // Applies |system_modal_| to |widget_|.
260 void UpdateSystemModal();
261
262 // Returns the "visible bounds" for the surface from the user's perspective.
263 gfx::Rect GetVisibleBounds() const;
264
265 // In the coordinate system of the parent root window.
266 gfx::Point GetMouseLocation() const;
267
Dominik Laskowski2d4316412017-12-13 19:14:44268 // In the local coordinate system of the window.
269 virtual gfx::Rect GetShadowBounds() const;
270
Mitsuru Oshima3e165792017-12-11 22:27:48271 // Attempt to start a drag operation. The type of drag operation to start is
272 // determined by |component|.
Mitsuru Oshima89e5c1352018-01-17 07:29:39273 // TODO(oshima): Move this to ShellSurface.
Mitsuru Oshima3e165792017-12-11 22:27:48274 void AttemptToStartDrag(int component);
275
276 // Set the parent window of this surface.
277 void SetParentWindow(aura::Window* parent);
278
Mitsuru Oshima014ad082018-03-30 22:36:06279 const gfx::Rect& geometry() const { return geometry_; }
280
Mitsuru Oshima3e165792017-12-11 22:27:48281 views::Widget* widget_ = nullptr;
282 aura::Window* parent_ = nullptr;
283 bool movement_disabled_ = false;
284 gfx::Point origin_;
285
286 // Container Window Id (see ash/public/cpp/shell_window_ids.h)
287 int container_;
288 bool ignore_window_bounds_changes_ = false;
289 gfx::Vector2d origin_offset_;
290 gfx::Vector2d pending_origin_offset_;
291 gfx::Vector2d pending_origin_offset_accumulator_;
292 int resize_component_ = HTCAPTION; // HT constant (see ui/base/hit_test.h)
293 int pending_resize_component_ = HTCAPTION;
294 base::Optional<gfx::Rect> shadow_bounds_;
295 bool shadow_bounds_changed_ = false;
296 std::unique_ptr<ash::WindowResizer> resizer_;
297 base::string16 title_;
Mitsuru Oshima11439772017-12-14 02:06:59298 std::unique_ptr<ui::CompositorLock> configure_compositor_lock_;
299 ConfigureCallback configure_callback_;
Mitsuru Oshima89e5c1352018-01-17 07:29:39300 // TODO(oshima): Remove this once the transition to new drag/resize
301 // complete. https://crbug.com/801666.
302 bool client_controlled_move_resize_ = true;
Mitsuru Oshima3e165792017-12-11 22:27:48303
304 private:
305 struct Config;
306
Mitsuru Oshima3e165792017-12-11 22:27:48307 // Called on widget creation to initialize its window state.
308 // TODO(reveman): Remove virtual functions below to avoid FBC problem.
309 virtual void InitializeWindowState(ash::wm::WindowState* window_state) = 0;
310
Mitsuru Oshima3e165792017-12-11 22:27:48311 // Returns the scale of the surface tree relative to the shell surface.
312 virtual float GetScale() const;
313
Mitsuru Oshima3e165792017-12-11 22:27:48314 // Returns the window that has capture during dragging.
315 virtual aura::Window* GetDragWindow();
316
317 // Creates the resizer for a dragging/resizing operation.
318 virtual std::unique_ptr<ash::WindowResizer> CreateWindowResizer(
319 aura::Window* window,
320 int component);
321
322 // Overridden from ui::EventHandler:
323 bool OnMouseDragged(const ui::MouseEvent& event) override;
324
325 // End current drag operation.
326 void EndDrag(bool revert);
327
328 // Return the origin of the widget/surface taking visible bounds and current
329 // resize direction into account.
330 virtual gfx::Point GetWidgetOrigin() const;
331 virtual gfx::Point GetSurfaceOrigin() const;
332
333 bool activatable_ = true;
334 bool can_minimize_ = true;
335 bool frame_enabled_ = false;
David Reveman786d3182017-12-20 22:04:33336 bool has_frame_colors_ = false;
337 SkColor active_frame_color_ = SK_ColorBLACK;
338 SkColor inactive_frame_color_ = SK_ColorBLACK;
Mitsuru Oshima3e165792017-12-11 22:27:48339 bool pending_show_widget_ = false;
340 std::string application_id_;
341 gfx::Rect geometry_;
342 gfx::Rect pending_geometry_;
343 base::RepeatingClosure close_callback_;
344 base::OnceClosure surface_destroyed_callback_;
Mitsuru Oshima3e165792017-12-11 22:27:48345 ScopedConfigure* scoped_configure_ = nullptr;
Mitsuru Oshima3e165792017-12-11 22:27:48346 base::circular_deque<std::unique_ptr<Config>> pending_configs_;
Mitsuru Oshima3e165792017-12-11 22:27:48347 bool system_modal_ = false;
348 bool non_system_modal_window_was_active_ = false;
349 gfx::ImageSkia icon_;
350 gfx::Size minimum_size_;
351 gfx::Size pending_minimum_size_;
352 gfx::Size maximum_size_;
353 gfx::Size pending_maximum_size_;
354
355 DISALLOW_COPY_AND_ASSIGN(ShellSurfaceBase);
356};
357
358} // namespace exo
359
360#endif // COMPONENTS_EXO_SHELL_SURFACE_BASE_H_