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_LIB_WINDOW_TREE_CLIENT_IMPL_H_ | |
6 #define COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_TREE_CLIENT_IMPL_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/cpp/window_tree_connection.h" | |
23 #include "components/mus/public/interfaces/window_tree.mojom.h" | |
24 #include "mojo/public/cpp/bindings/associated_binding.h" | |
25 #include "mojo/public/cpp/bindings/strong_binding.h" | |
26 | |
27 namespace gfx { | |
28 class Insets; | |
29 class Size; | |
30 } | |
31 | |
32 namespace mus { | |
33 class InFlightChange; | |
34 class WindowTreeClientImplPrivate; | |
35 class WindowTreeConnection; | |
36 class WindowTreeDelegate; | |
37 | |
38 enum class ChangeType; | |
39 | |
40 // Manages the connection with the Window Server service. | |
41 class WindowTreeClientImpl : public WindowTreeConnection, | |
42 public mojom::WindowTreeClient, | |
43 public mojom::WindowManager, | |
44 public WindowManagerClient { | |
45 public: | |
46 WindowTreeClientImpl(WindowTreeDelegate* delegate, | |
47 WindowManagerDelegate* window_manager_delegate, | |
48 mojo::InterfaceRequest<mojom::WindowTreeClient> request); | |
49 ~WindowTreeClientImpl() override; | |
50 | |
51 // Establishes the connection by way of the WindowTreeFactory. | |
52 void ConnectViaWindowTreeFactory(shell::Connector* connector); | |
53 | |
54 // Wait for OnEmbed(), returning when done. | |
55 void WaitForEmbed(); | |
56 | |
57 bool connected() const { return tree_ != nullptr; } | |
58 ClientSpecificId client_id() const { return client_id_; } | |
59 | |
60 // API exposed to the window implementations that pushes local changes to the | |
61 // service. | |
62 void DestroyWindow(Window* window); | |
63 | |
64 // These methods take TransportIds. For windows owned by the current client, | |
65 // the client id high word can be zero. In all cases, the TransportId 0x1 | |
66 // refers to the root window. | |
67 void AddChild(Window* parent, Id child_id); | |
68 void RemoveChild(Window* parent, Id child_id); | |
69 | |
70 void AddTransientWindow(Window* window, Id transient_window_id); | |
71 void RemoveTransientWindowFromParent(Window* window); | |
72 | |
73 void SetModal(Window* window); | |
74 | |
75 void Reorder(Window* window, | |
76 Id relative_window_id, | |
77 mojom::OrderDirection direction); | |
78 | |
79 // Returns true if the specified window was created by this client. | |
80 bool OwnsWindow(Window* window) const; | |
81 | |
82 void SetBounds(Window* window, | |
83 const gfx::Rect& old_bounds, | |
84 const gfx::Rect& bounds); | |
85 void SetCapture(Window* window); | |
86 void ReleaseCapture(Window* window); | |
87 void SetClientArea(Id window_id, | |
88 const gfx::Insets& client_area, | |
89 const std::vector<gfx::Rect>& additional_client_areas); | |
90 void SetHitTestMask(Id window_id, const gfx::Rect& mask); | |
91 void ClearHitTestMask(Id window_id); | |
92 void SetFocus(Window* window); | |
93 void SetCanFocus(Id window_id, bool can_focus); | |
94 void SetPredefinedCursor(Id window_id, mus::mojom::Cursor cursor_id); | |
95 void SetVisible(Window* window, bool visible); | |
96 void SetOpacity(Window* window, float opacity); | |
97 void SetProperty(Window* window, | |
98 const std::string& name, | |
99 mojo::Array<uint8_t> data); | |
100 void SetWindowTextInputState(Id window_id, mojo::TextInputStatePtr state); | |
101 void SetImeVisibility(Id window_id, | |
102 bool visible, | |
103 mojo::TextInputStatePtr state); | |
104 | |
105 void Embed(Id window_id, | |
106 mojom::WindowTreeClientPtr client, | |
107 const mojom::WindowTree::EmbedCallback& callback); | |
108 | |
109 void RequestClose(Window* window); | |
110 | |
111 void AttachSurface(Id window_id, | |
112 mojom::SurfaceType type, | |
113 mojo::InterfaceRequest<mojom::Surface> surface, | |
114 mojom::SurfaceClientPtr client); | |
115 | |
116 // Sets the input capture to |window| without notifying the server. | |
117 void LocalSetCapture(Window* window); | |
118 // Sets focus to |window| without notifying the server. | |
119 void LocalSetFocus(Window* window); | |
120 | |
121 // Start/stop tracking windows. While tracked, they can be retrieved via | |
122 // WindowTreeConnection::GetWindowById. | |
123 void AddWindow(Window* window); | |
124 | |
125 bool IsRoot(Window* window) const { return roots_.count(window) > 0; } | |
126 | |
127 void OnWindowDestroying(Window* window); | |
128 | |
129 // Called after the window's observers have been notified of destruction (as | |
130 // the last step of ~Window). | |
131 void OnWindowDestroyed(Window* window); | |
132 | |
133 Window* GetWindowByServerId(Id id); | |
134 | |
135 // WindowTreeConnection: | |
136 Window* GetCaptureWindow() override; | |
137 | |
138 private: | |
139 friend class WindowTreeClientImplPrivate; | |
140 | |
141 enum class NewWindowType { | |
142 CHILD, | |
143 TOP_LEVEL, | |
144 }; | |
145 | |
146 using IdToWindowMap = std::map<Id, Window*>; | |
147 | |
148 // TODO(sky): this assumes change_ids never wrap, which is a bad assumption. | |
149 using InFlightMap = std::map<uint32_t, std::unique_ptr<InFlightChange>>; | |
150 | |
151 // Returns the oldest InFlightChange that matches |change|. | |
152 InFlightChange* GetOldestInFlightChangeMatching(const InFlightChange& change); | |
153 | |
154 // See InFlightChange for details on how InFlightChanges are used. | |
155 uint32_t ScheduleInFlightChange(std::unique_ptr<InFlightChange> change); | |
156 | |
157 // Returns true if there is an InFlightChange that matches |change|. If there | |
158 // is an existing change SetRevertValueFrom() is invoked on it. Returns false | |
159 // if there is no InFlightChange matching |change|. | |
160 // See InFlightChange for details on how InFlightChanges are used. | |
161 bool ApplyServerChangeToExistingInFlightChange(const InFlightChange& change); | |
162 | |
163 Window* NewWindowImpl(NewWindowType type, | |
164 const Window::SharedProperties* properties); | |
165 | |
166 // OnEmbed() calls into this. Exposed as a separate function for testing. | |
167 void OnEmbedImpl(mojom::WindowTree* window_tree, | |
168 ClientSpecificId client_id, | |
169 mojom::WindowDataPtr root_data, | |
170 int64_t display_id, | |
171 Id focused_window_id, | |
172 bool drawn); | |
173 | |
174 void OnReceivedCursorLocationMemory(mojo::ScopedSharedBufferHandle handle); | |
175 | |
176 // Overridden from WindowTreeConnection: | |
177 void SetDeleteOnNoRoots(bool value) override; | |
178 const std::set<Window*>& GetRoots() override; | |
179 Window* GetFocusedWindow() override; | |
180 void ClearFocus() override; | |
181 gfx::Point GetCursorScreenPoint() override; | |
182 void SetEventObserver(mojom::EventMatcherPtr matcher) override; | |
183 Window* NewWindow(const Window::SharedProperties* properties) override; | |
184 Window* NewTopLevelWindow( | |
185 const Window::SharedProperties* properties) override; | |
186 void AddObserver(WindowTreeConnectionObserver* observer) override; | |
187 void RemoveObserver(WindowTreeConnectionObserver* observer) override; | |
188 | |
189 // Overridden from WindowTreeClient: | |
190 void OnEmbed(ClientSpecificId client_id, | |
191 mojom::WindowDataPtr root, | |
192 mojom::WindowTreePtr tree, | |
193 int64_t display_id, | |
194 Id focused_window_id, | |
195 bool drawn) override; | |
196 void OnEmbeddedAppDisconnected(Id window_id) override; | |
197 void OnUnembed(Id window_id) override; | |
198 void OnLostCapture(Id window_id) override; | |
199 void OnTopLevelCreated(uint32_t change_id, | |
200 mojom::WindowDataPtr data, | |
201 int64_t display_id, | |
202 bool drawn) override; | |
203 void OnWindowBoundsChanged(Id window_id, | |
204 const gfx::Rect& old_bounds, | |
205 const gfx::Rect& new_bounds) override; | |
206 void OnClientAreaChanged( | |
207 uint32_t window_id, | |
208 const gfx::Insets& new_client_area, | |
209 mojo::Array<gfx::Rect> new_additional_client_areas) override; | |
210 void OnTransientWindowAdded(uint32_t window_id, | |
211 uint32_t transient_window_id) override; | |
212 void OnTransientWindowRemoved(uint32_t window_id, | |
213 uint32_t transient_window_id) override; | |
214 void OnWindowHierarchyChanged( | |
215 Id window_id, | |
216 Id old_parent_id, | |
217 Id new_parent_id, | |
218 mojo::Array<mojom::WindowDataPtr> windows) override; | |
219 void OnWindowReordered(Id window_id, | |
220 Id relative_window_id, | |
221 mojom::OrderDirection direction) override; | |
222 void OnWindowDeleted(Id window_id) override; | |
223 void OnWindowVisibilityChanged(Id window_id, bool visible) override; | |
224 void OnWindowOpacityChanged(Id window_id, | |
225 float old_opacity, | |
226 float new_opacity) override; | |
227 void OnWindowParentDrawnStateChanged(Id window_id, bool drawn) override; | |
228 void OnWindowSharedPropertyChanged(Id window_id, | |
229 const mojo::String& name, | |
230 mojo::Array<uint8_t> new_data) override; | |
231 void OnWindowInputEvent(uint32_t event_id, | |
232 Id window_id, | |
233 mojom::EventPtr event, | |
234 uint32_t event_observer_id) override; | |
235 void OnEventObserved(mojom::EventPtr event, | |
236 uint32_t event_observer_id) override; | |
237 void OnWindowFocused(Id focused_window_id) override; | |
238 void OnWindowPredefinedCursorChanged(Id window_id, | |
239 mojom::Cursor cursor) override; | |
240 void OnChangeCompleted(uint32_t change_id, bool success) override; | |
241 void RequestClose(uint32_t window_id) override; | |
242 void GetWindowManager( | |
243 mojo::AssociatedInterfaceRequest<WindowManager> internal) override; | |
244 | |
245 // Overridden from WindowManager: | |
246 void WmSetBounds(uint32_t change_id, | |
247 Id window_id, | |
248 const gfx::Rect& transit_bounds) override; | |
249 void WmSetProperty(uint32_t change_id, | |
250 Id window_id, | |
251 const mojo::String& name, | |
252 mojo::Array<uint8_t> transit_data) override; | |
253 void WmCreateTopLevelWindow(uint32_t change_id, | |
254 ClientSpecificId requesting_client_id, | |
255 mojo::Map<mojo::String, mojo::Array<uint8_t>> | |
256 transport_properties) override; | |
257 void WmClientJankinessChanged(ClientSpecificId client_id, | |
258 bool janky) override; | |
259 void OnAccelerator(uint32_t id, mus::mojom::EventPtr event) override; | |
260 | |
261 // Overridden from WindowManagerClient: | |
262 void SetFrameDecorationValues( | |
263 mojom::FrameDecorationValuesPtr values) override; | |
264 void SetNonClientCursor(Window* window, | |
265 mus::mojom::Cursor cursor_id) override; | |
266 void AddAccelerator(uint32_t id, | |
267 mojom::EventMatcherPtr event_matcher, | |
268 const base::Callback<void(bool)>& callback) override; | |
269 void RemoveAccelerator(uint32_t id) override; | |
270 void AddActivationParent(Window* window) override; | |
271 void RemoveActivationParent(Window* window) override; | |
272 void ActivateNextWindow() override; | |
273 void SetUnderlaySurfaceOffsetAndExtendedHitArea( | |
274 Window* window, | |
275 const gfx::Vector2d& offset, | |
276 const gfx::Insets& hit_area) override; | |
277 | |
278 // This is set once and only once when we get OnEmbed(). It gives the unique | |
279 // id for this client. | |
280 ClientSpecificId client_id_; | |
281 | |
282 // Id assigned to the next window created. | |
283 ClientSpecificId next_window_id_; | |
284 | |
285 // Id used for the next change id supplied to the server. | |
286 uint32_t next_change_id_; | |
287 InFlightMap in_flight_map_; | |
288 | |
289 WindowTreeDelegate* delegate_; | |
290 | |
291 WindowManagerDelegate* window_manager_delegate_; | |
292 | |
293 std::set<Window*> roots_; | |
294 | |
295 IdToWindowMap windows_; | |
296 std::map<ClientSpecificId, std::set<Window*>> embedded_windows_; | |
297 | |
298 Window* capture_window_; | |
299 | |
300 Window* focused_window_; | |
301 | |
302 mojo::Binding<WindowTreeClient> binding_; | |
303 mojom::WindowTreePtr tree_ptr_; | |
304 // Typically this is the value contained in |tree_ptr_|, but tests may | |
305 // directly set this. | |
306 mojom::WindowTree* tree_; | |
307 | |
308 bool delete_on_no_roots_; | |
309 | |
310 bool in_destructor_; | |
311 | |
312 // A handle to shared memory that is one 32 bit integer long. The window | |
313 // server uses this to let us synchronously read the cursor location. | |
314 mojo::ScopedSharedBufferHandle cursor_location_handle_; | |
315 | |
316 // The one int in |cursor_location_handle_|. When we read from this | |
317 // location, we must always read from it atomically. | |
318 base::subtle::Atomic32* cursor_location_memory_; | |
319 | |
320 base::ObserverList<WindowTreeConnectionObserver> observers_; | |
321 | |
322 std::unique_ptr<mojo::AssociatedBinding<mojom::WindowManager>> | |
323 window_manager_internal_; | |
324 mojom::WindowManagerClientAssociatedPtr window_manager_internal_client_; | |
325 | |
326 bool has_event_observer_ = false; | |
327 | |
328 // Monotonically increasing ID for event observers. | |
329 uint32_t event_observer_id_ = 0u; | |
330 | |
331 base::WeakPtrFactory<WindowTreeClientImpl> weak_factory_; | |
332 | |
333 DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl); | |
334 }; | |
335 | |
336 } // namespace mus | |
337 | |
338 #endif // COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_TREE_CLIENT_IMPL_H_ | |
OLD | NEW |