| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_EXO_WAYLAND_ZCR_REMOTE_SHELL_IMPL_H_ |
| #define COMPONENTS_EXO_WAYLAND_ZCR_REMOTE_SHELL_IMPL_H_ |
| |
| #include <remote-shell-unstable-v1-server-protocol.h> |
| #include <remote-shell-unstable-v2-server-protocol.h> |
| |
| #include "ash/wm/window_state.h" |
| #include "base/memory/raw_ptr.h" |
| #include "components/exo/client_controlled_shell_surface.h" |
| #include "components/exo/input_method_surface.h" |
| #include "components/exo/notification_surface.h" |
| #include "components/exo/seat.h" |
| #include "components/exo/seat_observer.h" |
| #include "components/exo/surface.h" |
| #include "components/exo/toast_surface.h" |
| #include "components/exo/wayland/wayland_display_observer.h" |
| #include "components/exo/wayland/zcr_remote_shell.h" |
| #include "components/exo/wayland/zcr_remote_shell_event_mapping.h" |
| #include "ui/display/display_observer.h" |
| #include "ui/display/manager/display_manager_observer.h" |
| |
| namespace exo { |
| namespace wayland { |
| |
| using chromeos::WindowStateType; |
| |
| class WaylandRemoteOutput : public WaylandDisplayObserver { |
| public: |
| WaylandRemoteOutput(wl_resource* resource, |
| WaylandRemoteOutputEventMapping event_mapping, |
| WaylandDisplayHandler* display_handler); |
| WaylandRemoteOutput(const WaylandRemoteOutput&) = delete; |
| WaylandRemoteOutput& operator=(const WaylandRemoteOutput&) = delete; |
| ~WaylandRemoteOutput() override; |
| |
| // Overridden from WaylandDisplayObserver: |
| bool SendDisplayMetrics(const display::Display& display, |
| uint32_t changed_metrics) override; |
| void SendActiveDisplay() override; |
| void OnOutputDestroyed() override; |
| |
| private: |
| const raw_ptr<wl_resource> resource_; |
| |
| bool initial_config_sent_ = false; |
| |
| WaylandRemoteOutputEventMapping const event_mapping_; |
| |
| raw_ptr<WaylandDisplayHandler> display_handler_; |
| }; |
| |
| // Implements remote shell interface and monitors workspace state needed |
| // for the remote shell interface. |
| class WaylandRemoteShell : public display::DisplayObserver, |
| public SeatObserver, |
| public display::DisplayManagerObserver { |
| public: |
| using OutputResourceProvider = base::RepeatingCallback<wl_resource*(int64_t)>; |
| |
| WaylandRemoteShell(Display* display, |
| wl_resource* remote_shell_resource, |
| OutputResourceProvider output_provider, |
| WaylandRemoteShellEventMapping event_mapping, |
| bool use_default_scale_cancellation_default); |
| |
| WaylandRemoteShell(const WaylandRemoteShell&) = delete; |
| |
| WaylandRemoteShell& operator=(const WaylandRemoteShell&) = delete; |
| |
| ~WaylandRemoteShell() override; |
| |
| std::unique_ptr<ClientControlledShellSurface> CreateShellSurface( |
| Surface* surface, |
| int container); |
| |
| std::unique_ptr<ClientControlledShellSurface::Delegate> |
| CreateShellSurfaceDelegate(wl_resource* resource); |
| std::unique_ptr<NotificationSurface> CreateNotificationSurface( |
| Surface* surface, |
| const std::string& notification_key); |
| |
| std::unique_ptr<InputMethodSurface> CreateInputMethodSurface( |
| Surface* surface); |
| |
| std::unique_ptr<ToastSurface> CreateToastSurface(Surface* surface); |
| |
| void SetUseDefaultScaleCancellation(bool use_default_scale); |
| |
| void OnRemoteSurfaceDestroyed(wl_resource* resource); |
| |
| // Overridden from display::DisplayObserver: |
| void OnDisplayAdded(const display::Display& new_display) override; |
| void OnDisplaysRemoved(const display::Displays& removed_displays) override; |
| void OnDisplayTabletStateChanged(display::TabletState state) override; |
| void OnDisplayMetricsChanged(const display::Display& display, |
| uint32_t changed_metrics) override; |
| |
| // display::DisplayManagerObserver: |
| void OnWillProcessDisplayChanges() override; |
| void OnDidProcessDisplayChanges( |
| const DisplayConfigurationChange& configuration_change) override; |
| |
| // Overridden from SeatObserver: |
| void OnSurfaceFocused(Surface* gained_focus, |
| Surface* lost_focus, |
| bool has_focused_surface) override; |
| |
| WaylandRemoteShellEventMapping const event_mapping_; |
| |
| private: |
| friend class WaylandRemoteShellTest; |
| |
| void ScheduleSendDisplayMetrics(int delay_ms); |
| |
| // Returns the transform that a display's output is currently adjusted for. |
| wl_output_transform DisplayTransform(display::Display::Rotation rotation); |
| |
| void SendDisplayMetrics(); |
| |
| void FocusedSurfaceChanged(Surface* gained_active_surface, |
| Surface* lost_active_surface, |
| bool has_focused_client); |
| |
| void OnRemoteSurfaceBoundsChanged(wl_resource* resource, |
| WindowStateType current_state, |
| WindowStateType requested_state, |
| int64_t display_id, |
| const gfx::Rect& bounds_in_display, |
| bool resize, |
| int bounds_change, |
| bool is_adjusted_bounds); |
| |
| void SendBoundsChanged(wl_resource* resource, |
| int64_t display_id, |
| const gfx::Rect& bounds_in_display, |
| uint32_t reason); |
| |
| void OnRemoteSurfaceStateChanged(wl_resource* resource, |
| WindowStateType old_state_type, |
| WindowStateType new_state_type); |
| |
| void OnRemoteSurfaceChangeZoomLevel(wl_resource* resource, ZoomChange change); |
| |
| void OnRemoteSurfaceGeometryChanged(wl_resource* resource, |
| const gfx::Rect& geometry); |
| struct BoundsChangeData { |
| int64_t display_id; |
| gfx::Rect bounds_in_display; |
| uint32_t reason; |
| BoundsChangeData(int64_t display_id, |
| const gfx::Rect& bounds, |
| uint32_t reason) |
| : display_id(display_id), bounds_in_display(bounds), reason(reason) {} |
| }; |
| |
| // The exo display instance. Not owned. |
| const raw_ptr<Display> display_; |
| |
| // The remote shell resource associated with observer. |
| const raw_ptr<wl_resource> remote_shell_resource_; |
| |
| // Callback to get the wl_output resource for a given display_id. |
| OutputResourceProvider const output_provider_; |
| |
| // When true, the compositor should use the default_device_scale_factor to |
| // undo the scaling on the client buffers. When false, the compositor should |
| // use the device_scale_factor for the display for this scaling cancellation. |
| // in v2 this is always false. |
| bool use_default_scale_cancellation_; |
| |
| bool in_display_update_ = false; |
| bool needs_send_display_metrics_ = true; |
| |
| int layout_mode_ = ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_WINDOWED; |
| |
| base::flat_map<wl_resource*, BoundsChangeData> pending_bounds_changes_; |
| |
| bool last_has_focused_client_ = false; |
| |
| display::ScopedDisplayObserver display_observer_{this}; |
| |
| base::ScopedObservation<display::DisplayManager, |
| display::DisplayManagerObserver> |
| display_manager_observation_{this}; |
| |
| const raw_ptr<Seat> seat_; |
| |
| base::WeakPtrFactory<WaylandRemoteShell> weak_ptr_factory_{this}; |
| |
| friend class WaylandRemoteSurfaceDelegate; |
| }; |
| |
| class WaylandRemoteSurfaceDelegate |
| : public ClientControlledShellSurface::Delegate { |
| public: |
| WaylandRemoteSurfaceDelegate(base::WeakPtr<WaylandRemoteShell> shell, |
| wl_resource* resource, |
| WaylandRemoteShellEventMapping event_mapping); |
| ~WaylandRemoteSurfaceDelegate() override; |
| WaylandRemoteSurfaceDelegate(const WaylandRemoteSurfaceDelegate&) = delete; |
| WaylandRemoteSurfaceDelegate& operator=(const WaylandRemoteSurfaceDelegate&) = |
| delete; |
| |
| private: |
| // ClientControlledShellSurfaceDelegate: |
| void OnGeometryChanged(const gfx::Rect& geometry) override; |
| void OnStateChanged(chromeos::WindowStateType old_state_type, |
| chromeos::WindowStateType new_state_type) override; |
| void OnBoundsChanged(chromeos::WindowStateType current_state, |
| chromeos::WindowStateType requested_state, |
| int64_t display_id, |
| const gfx::Rect& bounds_in_display, |
| bool is_resize, |
| int bounds_change, |
| bool is_adjusted_bounds) override; |
| void OnDragStarted(int component) override; |
| void OnDragFinished(int x, int y, bool canceled) override; |
| void OnZoomLevelChanged(ZoomChange zoom_change) override; |
| |
| base::WeakPtr<WaylandRemoteShell> shell_; |
| raw_ptr<wl_resource> resource_; |
| WaylandRemoteShellEventMapping const event_mapping_; |
| }; |
| |
| namespace zcr_remote_shell { |
| |
| double GetDefaultDeviceScaleFactor(); |
| |
| gfx::Rect ScaleBoundsToPixelSnappedToParent( |
| const gfx::Size& parent_size_in_pixel, |
| const gfx::Size& parent_size, |
| float device_scale_factor, |
| const gfx::Rect& child_bounds); |
| |
| void remote_surface_destroy(wl_client* client, wl_resource* resource); |
| void remote_surface_set_app_id(wl_client* client, |
| wl_resource* resource, |
| const char* app_id); |
| void remote_surface_set_window_geometry(wl_client* client, |
| wl_resource* resource, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| void remote_surface_set_orientation(wl_client* client, |
| wl_resource* resource, |
| int32_t orientation); |
| |
| void remote_surface_set_title(wl_client* client, |
| wl_resource* resource, |
| const char* title); |
| void remote_surface_set_top_inset(wl_client* client, |
| wl_resource* resource, |
| int32_t height); |
| |
| void remote_surface_maximize(wl_client* client, wl_resource* resource); |
| void remote_surface_minimize(wl_client* client, wl_resource* resource); |
| void remote_surface_restore(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_fullscreen(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_pin(wl_client* client, |
| wl_resource* resource, |
| int32_t trusted); |
| |
| void remote_surface_unpin(wl_client* client, wl_resource* resource); |
| void remote_surface_set_system_modal(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_unset_system_modal(wl_client* client, |
| wl_resource* resource); |
| |
| void remote_surface_set_rectangular_surface_shadow(wl_client* client, |
| wl_resource* resource, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| void remote_surface_set_systemui_visibility(wl_client* client, |
| wl_resource* resource, |
| uint32_t visibility); |
| void remote_surface_set_always_on_top(wl_client* client, wl_resource* resource); |
| void remote_surface_unset_always_on_top(wl_client* client, |
| wl_resource* resource); |
| |
| void remote_surface_start_move(wl_client* client, |
| wl_resource* resource, |
| int32_t x, |
| int32_t y); |
| void remote_surface_set_can_maximize(wl_client* client, wl_resource* resource); |
| void remote_surface_unset_can_maximize(wl_client* client, |
| wl_resource* resource); |
| void remote_surface_set_min_size(wl_client* client, |
| wl_resource* resource, |
| int32_t width, |
| int32_t height); |
| void remote_surface_set_max_size(wl_client* client, |
| wl_resource* resource, |
| int32_t width, |
| int32_t height); |
| void remote_surface_set_aspect_ratio(wl_client* client, |
| wl_resource* resource, |
| int32_t aspect_ratio_width, |
| int32_t aspect_ratio_height); |
| void remote_surface_set_snapped_to_left(wl_client* client, |
| wl_resource* resource); |
| |
| void remote_surface_set_snapped_to_right(wl_client* client, |
| wl_resource* resource); |
| void remote_surface_start_resize(wl_client* client, |
| wl_resource* resource, |
| uint32_t direction, |
| int32_t x, |
| int32_t y); |
| void remote_surface_set_frame(wl_client* client, |
| wl_resource* resource, |
| uint32_t type); |
| void remote_surface_set_frame_buttons(wl_client* client, |
| wl_resource* resource, |
| uint32_t visible_button_mask, |
| uint32_t enabled_button_mask); |
| void remote_surface_set_extra_title(wl_client* client, |
| wl_resource* resource, |
| const char* extra_title); |
| void remote_surface_set_orientation_lock(wl_client* client, |
| wl_resource* resource, |
| uint32_t orientation_lock); |
| void remote_surface_pip(wl_client* client, wl_resource* resource); |
| void remote_surface_set_bounds(wl_client* client, |
| wl_resource* resource, |
| uint32_t display_id_hi, |
| uint32_t display_id_lo, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| |
| void remote_surface_set_accessibility_id_DEPRECATED(wl_client* client, |
| wl_resource* resource, |
| int32_t accessibility_id); |
| void remote_surface_set_pip_original_window(wl_client* client, |
| wl_resource* resource); |
| void remote_surface_unset_pip_original_window(wl_client* client, |
| wl_resource* resource); |
| |
| void remote_surface_set_system_gesture_exclusion(wl_client* client, |
| wl_resource* resource, |
| wl_resource* region_resource); |
| void remote_surface_set_resize_lock(wl_client* client, wl_resource* resource); |
| void remote_surface_unset_resize_lock(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_set_bounds_in_output(wl_client* client, |
| wl_resource* resource, |
| wl_resource* output_resource, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| |
| void remote_surface_set_resize_lock_type(wl_client* client, |
| wl_resource* resource, |
| uint32_t mode); |
| |
| void remote_surface_set_scale_factor(wl_client* client, |
| wl_resource* resource, |
| uint mode); |
| |
| void remote_surface_set_window_corner_radii(wl_client* client, |
| wl_resource* resource, |
| uint32_t upper_left_radius, |
| uint32_t upper_right_radius, |
| uint32_t lower_right_radius, |
| uint32_t lower_left_radius); |
| |
| void remote_surface_set_shadow_corner_radii(wl_client* client, |
| wl_resource* resource, |
| uint32_t upper_left_radius, |
| uint32_t upper_right_radius, |
| uint32_t lower_right_radius, |
| uint32_t lower_left_radius); |
| |
| void remote_surface_set_float(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_block_ime(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_unblock_ime(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_set_window_type(wl_client* client, |
| wl_resource* resource, |
| uint32_t type); |
| |
| void remote_surface_set_scale(wl_client* client, |
| wl_resource* resource, |
| wl_fixed_t scale); |
| |
| void remote_surface_activate(wl_client* client, |
| wl_resource* resource, |
| uint32_t serial); |
| |
| void remote_surface_unfullscreen(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_fullscreen(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_ack_configure_DEPRECATED(wl_client* client, |
| wl_resource* resource, |
| uint32_t serial); |
| |
| void remote_surface_move_DEPRECATED(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_resize_DEPRECATED(wl_client* client, wl_resource* resource); |
| |
| void remote_surface_set_resize_outset_DEPRECATED(wl_client* client, |
| wl_resource* resource, |
| int32_t outset); |
| |
| void remote_surface_set_rectangular_shadow_DEPRECATED(wl_client* client, |
| wl_resource* resource, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| |
| void remote_surface_set_rectangular_shadow_background_opacity_DEPRECATED( |
| wl_client* client, |
| wl_resource* resource, |
| wl_fixed_t opacity); |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // notification_surface_interface: |
| |
| void notification_surface_set_app_id(wl_client* client, |
| wl_resource* resource, |
| const char* app_id); |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // input_method_surface_interface: |
| |
| void input_method_surface_set_bounds_in_output(wl_client* client, |
| wl_resource* resource, |
| wl_resource* output_resource, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| |
| void input_method_surface_set_bounds(wl_client* client, |
| wl_resource* resource, |
| uint32_t display_id_hi, |
| uint32_t display_id_lo, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // toast_surface_interface: |
| |
| void toast_surface_set_bounds_in_output(wl_client* client, |
| wl_resource* resource, |
| wl_resource* output_resource, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| |
| void toast_surface_set_position(wl_client* client, |
| wl_resource* resource, |
| uint32_t display_id_hi, |
| uint32_t display_id_lo, |
| int32_t x, |
| int32_t y); |
| |
| void toast_surface_set_size(wl_client* client, |
| wl_resource* resource, |
| int32_t width, |
| int32_t height); |
| |
| void toast_surface_set_bounds_in_output(wl_client* client, |
| wl_resource* resource, |
| wl_resource* output_resource, |
| int32_t x, |
| int32_t y, |
| int32_t width, |
| int32_t height); |
| |
| void toast_surface_set_scale_factor(wl_client* client, |
| wl_resource* resource, |
| uint scale_factor_as_uint); |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // remote_shell_interface: |
| |
| void remote_shell_set_use_default_scale_cancellation( |
| wl_client*, |
| wl_resource* resource, |
| int32_t use_default_scale_cancellation); |
| |
| } // namespace zcr_remote_shell |
| } // namespace wayland |
| } // namespace exo |
| |
| #endif // COMPONENTS_EXO_WAYLAND_ZCR_REMOTE_SHELL_IMPL_H_ |