Chromium Code Reviews| 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 |
|
reveman
2017/03/02 02:00:38
I don't understand why we need to create another c
Dominik Laskowski
2017/03/03 13:50:41
Because from the perspective of SF and DMS/WMS/AMS
reveman
2017/03/06 19:02:13
This is android specific so very confusing to see
Dominik Laskowski
2017/03/08 23:13:22
But the server needs to know about the virtual dis
|
| +// 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, |