| Index: components/exo/wayland/server.cc
|
| diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
|
| index 4386237bcd910fbc612de340bd0b24620c6d5708..326bc42234a2f092a933db3b1e12f2c6770d4b53 100644
|
| --- a/components/exo/wayland/server.cc
|
| +++ b/components/exo/wayland/server.cc
|
| @@ -1983,7 +1983,7 @@ void remote_surface_ack_configure(wl_client* client,
|
| }
|
|
|
| void remote_surface_move(wl_client* client, wl_resource* resource) {
|
| - NOTIMPLEMENTED();
|
| + GetUserDataAs<ShellSurface>(resource)->Move();
|
| }
|
|
|
| const struct zcr_remote_surface_v1_interface remote_surface_implementation = {
|
| @@ -2024,6 +2024,25 @@ const struct zcr_notification_surface_v1_interface
|
|
|
| // Implements remote shell interface and monitors workspace state needed
|
| // for the remote shell interface.
|
| +//
|
| +// This class is also responsible for conversion between server-side screen
|
| +// coordinates and client-side virtual coordinates. This mapping enables
|
| +// support for multiple displays when the client is limited to a single
|
| +// display. In that case, the client uses a virtual display computed as
|
| +// the bounding box of the physical displays, and the server translates
|
| +// positions based on the display layout. For example, P is the client's
|
| +// origin in virtual coordinates, and Q is the server's origin in screen
|
| +// coordinates.
|
| +//
|
| +// P Q
|
| +// +-----+ /
|
| +// | |/
|
| +// | 2 +-----------+
|
| +// | | |
|
| +// +-----+ 1 |
|
| +// | |
|
| +// +-----------+
|
| +//
|
| class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
|
| public WMHelper::ActivationObserver,
|
| public display::DisplayObserver {
|
| @@ -2057,7 +2076,19 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
|
|
|
| std::unique_ptr<ShellSurface> CreateShellSurface(Surface* surface,
|
| int container) {
|
| - return display_->CreateRemoteShellSurface(surface, gfx::Point(), container);
|
| + gfx::Point origin = ComputeVirtualDisplayBounds().origin();
|
| + std::unique_ptr<ShellSurface> shell_surface =
|
| + display_->CreateRemoteShellSurface(surface, origin, container);
|
| +
|
| + if (IsMultiDisplaySupported()) {
|
| + shell_surface->set_display_config_changed_callback(base::Bind(
|
| + [](ShellSurface* shell_surface) {
|
| + shell_surface->SetOrigin(ComputeVirtualDisplayBounds().origin());
|
| + },
|
| + shell_surface.get()));
|
| + }
|
| +
|
| + return shell_surface;
|
| }
|
|
|
| std::unique_ptr<NotificationSurface> CreateNotificationSurface(
|
| @@ -2067,9 +2098,20 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
|
| }
|
|
|
| // Overridden from display::DisplayObserver:
|
| + void OnDisplayAdded(const display::Display& new_display) override {
|
| + if (IsMultiDisplaySupported())
|
| + ScheduleSendDisplayMetrics(0);
|
| + }
|
| +
|
| + void OnDisplayRemoved(const display::Display& old_display) override {
|
| + if (IsMultiDisplaySupported())
|
| + ScheduleSendDisplayMetrics(0);
|
| + }
|
| +
|
| void OnDisplayMetricsChanged(const display::Display& display,
|
| uint32_t changed_metrics) override {
|
| - if (display::Screen::GetScreen()->GetPrimaryDisplay().id() != display.id())
|
| + if (!IsMultiDisplaySupported() &&
|
| + display::Screen::GetScreen()->GetPrimaryDisplay().id() != display.id())
|
| return;
|
|
|
| // No need to update when a primary display has changed without bounds
|
| @@ -2113,15 +2155,18 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
|
| return;
|
| needs_send_display_metrics_ = false;
|
|
|
| - const display::Screen* screen = display::Screen::GetScreen();
|
| - const display::Display primary_display = screen->GetPrimaryDisplay();
|
| + display::Display primary_display =
|
| + display::Screen::GetScreen()->GetPrimaryDisplay();
|
|
|
| + gfx::Size display_size = IsMultiDisplaySupported()
|
| + ? ComputeVirtualDisplayBounds().size()
|
| + : primary_display.size();
|
| +
|
| + // TODO(domlaskowski): Send insets for each workspace.
|
| const gfx::Insets& work_area_insets = primary_display.GetWorkAreaInsets();
|
|
|
| zcr_remote_shell_v1_send_configuration_changed(
|
| - remote_shell_resource_,
|
| - primary_display.size().width(),
|
| - primary_display.size().height(),
|
| + remote_shell_resource_, display_size.width(), display_size.height(),
|
| OutputTransform(primary_display.rotation()),
|
| wl_fixed_from_double(primary_display.device_scale_factor()),
|
| work_area_insets.left(), work_area_insets.top(),
|
| @@ -2162,6 +2207,14 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
|
| wl_client_flush(client);
|
| }
|
|
|
| + static gfx::Rect ComputeVirtualDisplayBounds() {
|
| + // Virtual screen is the bounding box of the displays in screen coordinates.
|
| + gfx::Rect bounds;
|
| + for (const auto& display : display::Screen::GetScreen()->GetAllDisplays())
|
| + bounds.Union(display.bounds());
|
| + return bounds;
|
| + }
|
| +
|
| // The exo display instance. Not owned.
|
| Display* const display_;
|
|
|
| @@ -2314,7 +2367,7 @@ const struct zcr_remote_shell_v1_interface remote_shell_implementation = {
|
| remote_shell_destroy, remote_shell_get_remote_surface,
|
| remote_shell_get_notification_surface};
|
|
|
| -const uint32_t remote_shell_version = 2;
|
| +const uint32_t remote_shell_version = 3;
|
|
|
| void bind_remote_shell(wl_client* client,
|
| void* data,
|
|
|