OLD | NEW |
| (Empty) |
1 // Copyright 2014 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_MUS_PUBLIC_CPP_WINDOW_TREE_CLIENT_H_ | |
6 #define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_CLIENT_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <map> | |
11 #include <set> | |
12 #include <string> | |
13 #include <vector> | |
14 | |
15 #include "base/atomicops.h" | |
16 #include "base/macros.h" | |
17 #include "base/memory/weak_ptr.h" | |
18 #include "base/observer_list.h" | |
19 #include "components/mus/common/types.h" | |
20 #include "components/mus/public/cpp/window.h" | |
21 #include "components/mus/public/cpp/window_manager_delegate.h" | |
22 #include "components/mus/public/interfaces/window_tree.mojom.h" | |
23 #include "mojo/public/cpp/bindings/associated_binding.h" | |
24 #include "mojo/public/cpp/bindings/strong_binding.h" | |
25 | |
26 namespace display { | |
27 class Display; | |
28 } | |
29 | |
30 namespace gfx { | |
31 class Insets; | |
32 class Size; | |
33 } | |
34 | |
35 namespace shell { | |
36 class Connector; | |
37 } | |
38 | |
39 namespace mus { | |
40 class InFlightChange; | |
41 class WindowTreeClientDelegate; | |
42 class WindowTreeClientPrivate; | |
43 class WindowTreeClientObserver; | |
44 enum class ChangeType; | |
45 | |
46 // Manages the connection with mus. | |
47 // | |
48 // WindowTreeClient is deleted by any of the following: | |
49 // . If all the roots of the connection are destroyed and the connection is | |
50 // configured to delete when there are no roots (true if the WindowTreeClient | |
51 // is created with a mojom::WindowTreeClientRequest). This happens | |
52 // if the owner of the roots Embed()s another app in all the roots, or all | |
53 // the roots are explicitly deleted. | |
54 // . The connection to mus is lost. | |
55 // . Explicitly by way of calling delete. | |
56 // | |
57 // When WindowTreeClient is deleted all windows are deleted (and observers | |
58 // notified). This is followed by calling | |
59 // WindowTreeClientDelegate::OnDidDestroyClient(). | |
60 class WindowTreeClient : public mojom::WindowTreeClient, | |
61 public mojom::WindowManager, | |
62 public WindowManagerClient { | |
63 public: | |
64 WindowTreeClient(WindowTreeClientDelegate* delegate, | |
65 WindowManagerDelegate* window_manager_delegate, | |
66 mojom::WindowTreeClientRequest request); | |
67 ~WindowTreeClient() override; | |
68 | |
69 // Establishes the connection by way of the WindowTreeFactory. | |
70 void ConnectViaWindowTreeFactory(shell::Connector* connector); | |
71 | |
72 // Establishes the connection by way of WindowManagerWindowTreeFactory. | |
73 void ConnectAsWindowManager(shell::Connector* connector); | |
74 | |
75 // Wait for OnEmbed(), returning when done. | |
76 void WaitForEmbed(); | |
77 | |
78 bool connected() const { return tree_ != nullptr; } | |
79 ClientSpecificId client_id() const { return client_id_; } | |
80 | |
81 // API exposed to the window implementations that pushes local changes to the | |
82 // service. | |
83 void DestroyWindow(Window* window); | |
84 | |
85 // These methods take TransportIds. For windows owned by the current client, | |
86 // the client id high word can be zero. In all cases, the TransportId 0x1 | |
87 // refers to the root window. | |
88 void AddChild(Window* parent, Id child_id); | |
89 void RemoveChild(Window* parent, Id child_id); | |
90 | |
91 void AddTransientWindow(Window* window, Id transient_window_id); | |
92 void RemoveTransientWindowFromParent(Window* window); | |
93 | |
94 void SetModal(Window* window); | |
95 | |
96 void Reorder(Window* window, | |
97 Id relative_window_id, | |
98 mojom::OrderDirection direction); | |
99 | |
100 // Returns true if the specified window was created by this client. | |
101 bool OwnsWindow(Window* window) const; | |
102 | |
103 void SetBounds(Window* window, | |
104 const gfx::Rect& old_bounds, | |
105 const gfx::Rect& bounds); | |
106 void SetCapture(Window* window); | |
107 void ReleaseCapture(Window* window); | |
108 void SetClientArea(Id window_id, | |
109 const gfx::Insets& client_area, | |
110 const std::vector<gfx::Rect>& additional_client_areas); | |
111 void SetHitTestMask(Id window_id, const gfx::Rect& mask); | |
112 void ClearHitTestMask(Id window_id); | |
113 void SetFocus(Window* window); | |
114 void SetCanFocus(Id window_id, bool can_focus); | |
115 void SetPredefinedCursor(Id window_id, mus::mojom::Cursor cursor_id); | |
116 void SetVisible(Window* window, bool visible); | |
117 void SetOpacity(Window* window, float opacity); | |
118 void SetProperty(Window* window, | |
119 const std::string& name, | |
120 mojo::Array<uint8_t> data); | |
121 void SetWindowTextInputState(Id window_id, mojo::TextInputStatePtr state); | |
122 void SetImeVisibility(Id window_id, | |
123 bool visible, | |
124 mojo::TextInputStatePtr state); | |
125 | |
126 void Embed(Id window_id, | |
127 mojom::WindowTreeClientPtr client, | |
128 uint32_t flags, | |
129 const mojom::WindowTree::EmbedCallback& callback); | |
130 | |
131 void RequestClose(Window* window); | |
132 | |
133 void AttachSurface(Id window_id, | |
134 mojom::SurfaceType type, | |
135 mojo::InterfaceRequest<mojom::Surface> surface, | |
136 mojom::SurfaceClientPtr client); | |
137 | |
138 // Sets the input capture to |window| without notifying the server. | |
139 void LocalSetCapture(Window* window); | |
140 // Sets focus to |window| without notifying the server. | |
141 void LocalSetFocus(Window* window); | |
142 | |
143 // Start/stop tracking windows. While tracked, they can be retrieved via | |
144 // WindowTreeClient::GetWindowById. | |
145 void AddWindow(Window* window); | |
146 | |
147 bool IsRoot(Window* window) const { return roots_.count(window) > 0; } | |
148 | |
149 void OnWindowDestroying(Window* window); | |
150 | |
151 // Called after the window's observers have been notified of destruction (as | |
152 // the last step of ~Window). | |
153 void OnWindowDestroyed(Window* window); | |
154 | |
155 Window* GetWindowByServerId(Id id); | |
156 | |
157 // Sets whether this is deleted when there are no roots. The default is to | |
158 // delete when there are no roots. | |
159 void SetDeleteOnNoRoots(bool value); | |
160 | |
161 // Returns the root of this connection. | |
162 const std::set<Window*>& GetRoots(); | |
163 | |
164 // Returns the Window with input capture; null if no window has requested | |
165 // input capture, or if another app has capture. | |
166 Window* GetCaptureWindow(); | |
167 | |
168 // Returns the focused window; null if focus is not yet known or another app | |
169 // is focused. | |
170 Window* GetFocusedWindow(); | |
171 | |
172 // Sets focus to null. This does nothing if focus is currently null. | |
173 void ClearFocus(); | |
174 | |
175 // Returns the current location of the mouse on screen. Note: this method may | |
176 // race the asynchronous initialization; but in that case we return (0, 0). | |
177 gfx::Point GetCursorScreenPoint(); | |
178 | |
179 // See description in window_tree.mojom. When an existing event observer is | |
180 // updated or cleared then any future events from the server for that observer | |
181 // will be ignored. | |
182 void SetEventObserver(mojom::EventMatcherPtr matcher); | |
183 | |
184 // Creates and returns a new Window (which is owned by the window server). | |
185 // Windows are initially hidden, use SetVisible(true) to show. | |
186 Window* NewWindow() { return NewWindow(nullptr); } | |
187 Window* NewWindow( | |
188 const std::map<std::string, std::vector<uint8_t>>* properties); | |
189 Window* NewTopLevelWindow( | |
190 const std::map<std::string, std::vector<uint8_t>>* properties); | |
191 | |
192 void AddObserver(WindowTreeClientObserver* observer); | |
193 void RemoveObserver(WindowTreeClientObserver* observer); | |
194 | |
195 #if !defined(NDEBUG) | |
196 std::string GetDebugWindowHierarchy() const; | |
197 void BuildDebugInfo(const std::string& depth, | |
198 Window* window, | |
199 std::string* result) const; | |
200 #endif | |
201 | |
202 private: | |
203 friend class WindowTreeClientPrivate; | |
204 | |
205 enum class NewWindowType { | |
206 CHILD, | |
207 TOP_LEVEL, | |
208 }; | |
209 | |
210 using IdToWindowMap = std::map<Id, Window*>; | |
211 | |
212 // TODO(sky): this assumes change_ids never wrap, which is a bad assumption. | |
213 using InFlightMap = std::map<uint32_t, std::unique_ptr<InFlightChange>>; | |
214 | |
215 // Returns the oldest InFlightChange that matches |change|. | |
216 InFlightChange* GetOldestInFlightChangeMatching(const InFlightChange& change); | |
217 | |
218 // See InFlightChange for details on how InFlightChanges are used. | |
219 uint32_t ScheduleInFlightChange(std::unique_ptr<InFlightChange> change); | |
220 | |
221 // Returns true if there is an InFlightChange that matches |change|. If there | |
222 // is an existing change SetRevertValueFrom() is invoked on it. Returns false | |
223 // if there is no InFlightChange matching |change|. | |
224 // See InFlightChange for details on how InFlightChanges are used. | |
225 bool ApplyServerChangeToExistingInFlightChange(const InFlightChange& change); | |
226 | |
227 Window* NewWindowImpl(NewWindowType type, | |
228 const Window::SharedProperties* properties); | |
229 | |
230 // Sets the mojom::WindowTree implementation. | |
231 void SetWindowTree(mojom::WindowTreePtr window_tree_ptr); | |
232 | |
233 // Called when the mojom::WindowTree connection is lost, deletes this. | |
234 void OnConnectionLost(); | |
235 | |
236 // OnEmbed() calls into this. Exposed as a separate function for testing. | |
237 void OnEmbedImpl(mojom::WindowTree* window_tree, | |
238 ClientSpecificId client_id, | |
239 mojom::WindowDataPtr root_data, | |
240 int64_t display_id, | |
241 Id focused_window_id, | |
242 bool drawn); | |
243 | |
244 // Called by WmNewDisplayAdded(). | |
245 void WmNewDisplayAddedImpl(const display::Display& display, | |
246 mojom::WindowDataPtr root_data, | |
247 bool parent_drawn); | |
248 | |
249 void OnReceivedCursorLocationMemory(mojo::ScopedSharedBufferHandle handle); | |
250 | |
251 // Overridden from WindowTreeClient: | |
252 void OnEmbed(ClientSpecificId client_id, | |
253 mojom::WindowDataPtr root, | |
254 mojom::WindowTreePtr tree, | |
255 int64_t display_id, | |
256 Id focused_window_id, | |
257 bool drawn) override; | |
258 void OnEmbeddedAppDisconnected(Id window_id) override; | |
259 void OnUnembed(Id window_id) override; | |
260 void OnLostCapture(Id window_id) override; | |
261 void OnTopLevelCreated(uint32_t change_id, | |
262 mojom::WindowDataPtr data, | |
263 int64_t display_id, | |
264 bool drawn) override; | |
265 void OnWindowBoundsChanged(Id window_id, | |
266 const gfx::Rect& old_bounds, | |
267 const gfx::Rect& new_bounds) override; | |
268 void OnClientAreaChanged( | |
269 uint32_t window_id, | |
270 const gfx::Insets& new_client_area, | |
271 mojo::Array<gfx::Rect> new_additional_client_areas) override; | |
272 void OnTransientWindowAdded(uint32_t window_id, | |
273 uint32_t transient_window_id) override; | |
274 void OnTransientWindowRemoved(uint32_t window_id, | |
275 uint32_t transient_window_id) override; | |
276 void OnWindowHierarchyChanged( | |
277 Id window_id, | |
278 Id old_parent_id, | |
279 Id new_parent_id, | |
280 mojo::Array<mojom::WindowDataPtr> windows) override; | |
281 void OnWindowReordered(Id window_id, | |
282 Id relative_window_id, | |
283 mojom::OrderDirection direction) override; | |
284 void OnWindowDeleted(Id window_id) override; | |
285 void OnWindowVisibilityChanged(Id window_id, bool visible) override; | |
286 void OnWindowOpacityChanged(Id window_id, | |
287 float old_opacity, | |
288 float new_opacity) override; | |
289 void OnWindowParentDrawnStateChanged(Id window_id, bool drawn) override; | |
290 void OnWindowSharedPropertyChanged(Id window_id, | |
291 const mojo::String& name, | |
292 mojo::Array<uint8_t> new_data) override; | |
293 void OnWindowInputEvent(uint32_t event_id, | |
294 Id window_id, | |
295 std::unique_ptr<ui::Event> event, | |
296 uint32_t event_observer_id) override; | |
297 void OnEventObserved(std::unique_ptr<ui::Event> event, | |
298 uint32_t event_observer_id) override; | |
299 void OnWindowFocused(Id focused_window_id) override; | |
300 void OnWindowPredefinedCursorChanged(Id window_id, | |
301 mojom::Cursor cursor) override; | |
302 void OnChangeCompleted(uint32_t change_id, bool success) override; | |
303 void RequestClose(uint32_t window_id) override; | |
304 void GetWindowManager( | |
305 mojo::AssociatedInterfaceRequest<WindowManager> internal) override; | |
306 | |
307 // Overridden from WindowManager: | |
308 void OnConnect(ClientSpecificId client_id) override; | |
309 void WmNewDisplayAdded(mojom::DisplayPtr display, | |
310 mojom::WindowDataPtr root_data, | |
311 bool parent_drawn) override; | |
312 void WmSetBounds(uint32_t change_id, | |
313 Id window_id, | |
314 const gfx::Rect& transit_bounds) override; | |
315 void WmSetProperty(uint32_t change_id, | |
316 Id window_id, | |
317 const mojo::String& name, | |
318 mojo::Array<uint8_t> transit_data) override; | |
319 void WmCreateTopLevelWindow(uint32_t change_id, | |
320 ClientSpecificId requesting_client_id, | |
321 mojo::Map<mojo::String, mojo::Array<uint8_t>> | |
322 transport_properties) override; | |
323 void WmClientJankinessChanged(ClientSpecificId client_id, | |
324 bool janky) override; | |
325 void OnAccelerator(uint32_t id, std::unique_ptr<ui::Event> event) override; | |
326 | |
327 // Overridden from WindowManagerClient: | |
328 void SetFrameDecorationValues( | |
329 mojom::FrameDecorationValuesPtr values) override; | |
330 void SetNonClientCursor(Window* window, | |
331 mus::mojom::Cursor cursor_id) override; | |
332 void AddAccelerator(uint32_t id, | |
333 mojom::EventMatcherPtr event_matcher, | |
334 const base::Callback<void(bool)>& callback) override; | |
335 void RemoveAccelerator(uint32_t id) override; | |
336 void AddActivationParent(Window* window) override; | |
337 void RemoveActivationParent(Window* window) override; | |
338 void ActivateNextWindow() override; | |
339 void SetUnderlaySurfaceOffsetAndExtendedHitArea( | |
340 Window* window, | |
341 const gfx::Vector2d& offset, | |
342 const gfx::Insets& hit_area) override; | |
343 | |
344 // The one int in |cursor_location_mapping_|. When we read from this | |
345 // location, we must always read from it atomically. | |
346 base::subtle::Atomic32* cursor_location_memory() { | |
347 return reinterpret_cast<base::subtle::Atomic32*>( | |
348 cursor_location_mapping_.get()); | |
349 } | |
350 | |
351 // This is set once and only once when we get OnEmbed(). It gives the unique | |
352 // id for this client. | |
353 ClientSpecificId client_id_; | |
354 | |
355 // Id assigned to the next window created. | |
356 ClientSpecificId next_window_id_; | |
357 | |
358 // Id used for the next change id supplied to the server. | |
359 uint32_t next_change_id_; | |
360 InFlightMap in_flight_map_; | |
361 | |
362 WindowTreeClientDelegate* delegate_; | |
363 | |
364 WindowManagerDelegate* window_manager_delegate_; | |
365 | |
366 std::set<Window*> roots_; | |
367 | |
368 IdToWindowMap windows_; | |
369 std::map<ClientSpecificId, std::set<Window*>> embedded_windows_; | |
370 | |
371 Window* capture_window_; | |
372 | |
373 Window* focused_window_; | |
374 | |
375 mojo::Binding<mojom::WindowTreeClient> binding_; | |
376 mojom::WindowTreePtr tree_ptr_; | |
377 // Typically this is the value contained in |tree_ptr_|, but tests may | |
378 // directly set this. | |
379 mojom::WindowTree* tree_; | |
380 | |
381 bool delete_on_no_roots_; | |
382 | |
383 bool in_destructor_; | |
384 | |
385 // A mapping to shared memory that is one 32 bit integer long. The window | |
386 // server uses this to let us synchronously read the cursor location. | |
387 mojo::ScopedSharedBufferMapping cursor_location_mapping_; | |
388 | |
389 base::ObserverList<WindowTreeClientObserver> observers_; | |
390 | |
391 std::unique_ptr<mojo::AssociatedBinding<mojom::WindowManager>> | |
392 window_manager_internal_; | |
393 mojom::WindowManagerClientAssociatedPtr window_manager_internal_client_; | |
394 | |
395 bool has_event_observer_ = false; | |
396 | |
397 // Monotonically increasing ID for event observers. | |
398 uint32_t event_observer_id_ = 0u; | |
399 | |
400 base::WeakPtrFactory<WindowTreeClient> weak_factory_; | |
401 | |
402 DISALLOW_COPY_AND_ASSIGN(WindowTreeClient); | |
403 }; | |
404 | |
405 } // namespace mus | |
406 | |
407 #endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_CLIENT_H_ | |
OLD | NEW |