// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef SERVICES_UI_WS_WINDOW_MANAGER_STATE_H_ #define SERVICES_UI_WS_WINDOW_MANAGER_STATE_H_ #include #include #include #include #include #include #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "services/ui/public/interfaces/display_manager.mojom.h" #include "services/ui/ws/event_dispatcher.h" #include "services/ui/ws/event_dispatcher_delegate.h" #include "services/ui/ws/server_window_observer.h" #include "services/ui/ws/user_id.h" #include "services/ui/ws/window_server.h" namespace ui { namespace ws { class DisplayManager; class PlatformDisplay; class WindowManagerDisplayRoot; class WindowTree; namespace test { class WindowManagerStateTestApi; } // Manages state specific to a WindowManager that is shared across displays. // WindowManagerState is owned by the WindowTree the window manager is // associated with. class WindowManagerState : public EventDispatcherDelegate, public ServerWindowObserver { public: explicit WindowManagerState(WindowTree* window_tree); ~WindowManagerState() override; const UserId& user_id() const; WindowTree* window_tree() { return window_tree_; } const WindowTree* window_tree() const { return window_tree_; } void OnWillDestroyTree(WindowTree* tree); void SetFrameDecorationValues(mojom::FrameDecorationValuesPtr values); const mojom::FrameDecorationValues& frame_decoration_values() const { return *frame_decoration_values_; } bool got_frame_decoration_values() const { return got_frame_decoration_values_; } bool SetCapture(ServerWindow* window, ClientSpecificId client_id); ServerWindow* capture_window() { return event_dispatcher_.capture_window(); } const ServerWindow* capture_window() const { return event_dispatcher_.capture_window(); } void ReleaseCaptureBlockedByModalWindow(const ServerWindow* modal_window); void ReleaseCaptureBlockedByAnyModalWindow(); void SetDragDropSourceWindow( DragSource* drag_source, ServerWindow* window, DragTargetConnection* source_connection, const std::unordered_map>& drag_data, uint32_t drag_operation); void CancelDragDrop(); void EndDragDrop(); void AddSystemModalWindow(ServerWindow* window); // Deletes the WindowManagerDisplayRoot whose root is |display_root|. void DeleteWindowManagerDisplayRoot(ServerWindow* display_root); // Returns the ServerWindow corresponding to an orphaned root with the // specified id. See |orphaned_window_manager_display_roots_| for details on // what on orphaned root is. ServerWindow* GetOrphanedRootWithId(const WindowId& id); // TODO(sky): EventDispatcher is really an implementation detail and should // not be exposed. EventDispatcher* event_dispatcher() { return &event_dispatcher_; } // Returns true if this is the WindowManager of the active user. bool IsActive() const; void Activate(const gfx::Point& mouse_location_on_screen); void Deactivate(); // Processes an event from PlatformDisplay. void ProcessEvent(const Event& event, int64_t display_id); // Called when the ack from an event dispatched to WindowTree |tree| is // received. // TODO(sky): make this private and use a callback. void OnEventAck(mojom::WindowTree* tree, mojom::EventResult result); // Called when the WindowManager acks an accelerator. void OnAcceleratorAck( mojom::EventResult result, const std::unordered_map>& properties); private: class ProcessedEventTarget; friend class Display; friend class test::WindowManagerStateTestApi; // Set of display roots. This is a vector rather than a set to support removal // without deleting. using WindowManagerDisplayRoots = std::vector>; enum class DebugAcceleratorType { PRINT_WINDOWS, }; struct DebugAccelerator { bool Matches(const KeyEvent& event) const; DebugAcceleratorType type; KeyboardCode key_code; int event_flags; }; enum class EventDispatchPhase { // Not actively dispatching. NONE, // A PRE_TARGET accelerator has been encountered and we're awaiting the ack. PRE_TARGET_ACCELERATOR, // Dispatching to the target, awaiting the ack. TARGET, }; // There are two types of events that may be queued, both occur only when // waiting for an ack from a client. // . We get an event from the PlatformDisplay. This results in |event| being // set, but |processed_target| is null. // . We get an event from the EventDispatcher. In this case both |event| and // |processed_target| are valid. // The second case happens if EventDispatcher generates more than one event // at a time. struct QueuedEvent { QueuedEvent(); ~QueuedEvent(); std::unique_ptr event; std::unique_ptr processed_target; int64_t display_id; }; // Tracks state associated with an event being dispatched to a client. struct InFlightEventDetails { InFlightEventDetails(WindowTree* tree, int64_t display_id, const Event& event, EventDispatchPhase phase); ~InFlightEventDetails(); base::OneShotTimer timer; WindowTree* tree; int64_t display_id; std::unique_ptr event; EventDispatchPhase phase; }; const WindowServer* window_server() const; WindowServer* window_server(); DisplayManager* display_manager(); const DisplayManager* display_manager() const; // Adds |display_root| to the set of WindowManagerDisplayRoots owned by this // WindowManagerState. void AddWindowManagerDisplayRoot( std::unique_ptr display_root); // Called when a Display is deleted. void OnDisplayDestroying(Display* display); // Sets the visibility of all window manager roots windows to |value|. void SetAllRootWindowsVisible(bool value); // Returns the ServerWindow that is the root of the WindowManager for // |window|. |window| corresponds to the root of a Display. ServerWindow* GetWindowManagerRoot(ServerWindow* window); // Called if the client doesn't ack an event in the appropriate amount of // time. void OnEventAckTimeout(ClientSpecificId client_id); // Implemenation of processing an event with a match phase of all. This // handles debug accelerators and forwards to EventDispatcher. void ProcessEventImpl(const Event& event, int64_t display_id); // Schedules an event to be processed later. void QueueEvent(const Event& event, std::unique_ptr processed_event_target, int64_t display_id); // Processes the next valid event in |event_queue_|. If the event has already // been processed it is dispatched, otherwise the event is passed to the // EventDispatcher for processing. void ProcessNextEventFromQueue(); // Dispatches the event to the appropriate client and starts the ack timer. void DispatchInputEventToWindowImpl(ServerWindow* target, ClientSpecificId client_id, const Event& event, base::WeakPtr accelerator); // Registers accelerators used internally for debugging. void AddDebugAccelerators(); // Finds the debug accelerator for |event| and if one is found calls // HandleDebugAccelerator(). void ProcessDebugAccelerator(const Event& event); // Runs the specified debug accelerator. void HandleDebugAccelerator(DebugAcceleratorType type); // Called when waiting for an event or accelerator to be processed by |tree|. void ScheduleInputEventTimeout(WindowTree* tree, ServerWindow* target, const Event& event, EventDispatchPhase phase); // EventDispatcherDelegate: void OnAccelerator(uint32_t accelerator_id, const Event& event, AcceleratorPhase phase) override; void SetFocusedWindowFromEventDispatcher(ServerWindow* window) override; ServerWindow* GetFocusedWindowForEventDispatcher() override; void SetNativeCapture(ServerWindow* window) override; void ReleaseNativeCapture() override; void UpdateNativeCursorFromDispatcher() override; void OnCaptureChanged(ServerWindow* new_capture, ServerWindow* old_capture) override; void OnMouseCursorLocationChanged(const gfx::Point& point) override; void DispatchInputEventToWindow(ServerWindow* target, ClientSpecificId client_id, const Event& event, Accelerator* accelerator) override; ClientSpecificId GetEventTargetClientId(const ServerWindow* window, bool in_nonclient_area) override; ServerWindow* GetRootWindowContaining(gfx::Point* location) override; void OnEventTargetNotFound(const Event& event) override; // ServerWindowObserver: void OnWindowEmbeddedAppDisconnected(ServerWindow* window) override; // The single WindowTree this WindowManagerState is associated with. // |window_tree_| owns this. WindowTree* window_tree_; // Set to true the first time SetFrameDecorationValues() is called. bool got_frame_decoration_values_ = false; mojom::FrameDecorationValuesPtr frame_decoration_values_; base::WeakPtr post_target_accelerator_; std::queue> event_queue_; std::vector debug_accelerators_; // If non-null we're actively waiting for a response from a client for an // event. std::unique_ptr in_flight_event_details_; EventDispatcher event_dispatcher_; // PlatformDisplay that currently has capture. PlatformDisplay* platform_display_with_capture_ = nullptr; // All the active WindowManagerDisplayRoots. WindowManagerDisplayRoots window_manager_display_roots_; // Id of the display the current event being processed originated from. int64_t event_processing_display_id_ = 0; // Set of WindowManagerDisplayRoots corresponding to Displays that have been // destroyed. WindowManagerDisplayRoots are not destroyed immediately when // the Display is destroyed to allow the client to destroy the window when it // wants to. Once the client destroys the window WindowManagerDisplayRoots is // destroyed. WindowManagerDisplayRoots orphaned_window_manager_display_roots_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(WindowManagerState); }; } // namespace ws } // namespace ui #endif // SERVICES_UI_WS_WINDOW_MANAGER_STATE_H_