| 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 |