Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Unified Diff: components/exo/wayland/server.cc

Issue 2645663004: exo: Initial support for multiple displays in ARC (Closed)
Patch Set: Rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/exo/shell_surface_unittest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/exo/wayland/server.cc
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index 88a81a0edec22c43fe8e89e4386d98aac784f3d8..49c323f8870e977356326d535278b5b7657bacb9 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -27,6 +27,7 @@
#include <cstdlib>
#include <iterator>
#include <string>
+#include <unordered_set>
#include <utility>
#include "ash/public/cpp/shell_window_ids.h"
@@ -1005,7 +1006,8 @@ uint32_t HandleShellSurfaceConfigureCallback(
const gfx::Size& size,
ash::wm::WindowStateType state_type,
bool resizing,
- bool activated) {
+ bool activated,
+ const gfx::Point& origin) {
wl_shell_surface_send_configure(resource, WL_SHELL_SURFACE_RESIZE_NONE,
size.width(), size.height());
wl_client_flush(wl_resource_get_client(resource));
@@ -1530,7 +1532,8 @@ uint32_t HandleXdgToplevelV6ConfigureCallback(
const gfx::Size& size,
ash::wm::WindowStateType state_type,
bool resizing,
- bool activated) {
+ bool activated,
+ const gfx::Point& origin) {
wl_array states;
wl_array_init(&states);
if (state_type == ash::wm::WINDOW_STATE_TYPE_MAXIMIZED)
@@ -1667,7 +1670,8 @@ uint32_t HandleXdgSurfaceV5ConfigureCallback(
const gfx::Size& size,
ash::wm::WindowStateType state_type,
bool resizing,
- bool activated) {
+ bool activated,
+ const gfx::Point& origin) {
wl_array states;
wl_array_init(&states);
if (state_type == ash::wm::WINDOW_STATE_TYPE_MAXIMIZED)
@@ -1976,11 +1980,11 @@ void remote_surface_set_rectangular_surface_shadow(wl_client* client,
void remote_surface_ack_configure(wl_client* client,
wl_resource* resource,
uint32_t serial) {
- NOTIMPLEMENTED();
+ GetUserDataAs<ShellSurface>(resource)->AcknowledgeConfigure(serial);
}
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 = {
@@ -2021,6 +2025,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 {
@@ -2050,7 +2073,19 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
std::unique_ptr<ShellSurface> CreateShellSurface(Surface* surface,
int container) {
- return display_->CreateRemoteShellSurface(surface, container);
+ std::unique_ptr<ShellSurface> shell_surface =
+ display_->CreateRemoteShellSurface(surface, virtual_origin_, container);
+
+ shell_surfaces_.insert(shell_surface.get());
+ shell_surface->set_destroyed_callback(
+ base::Bind(&WaylandRemoteShell::OnShellSurfaceDestroyed,
+ weak_ptr_factory_.GetWeakPtr(), shell_surface.get()));
+
+ return shell_surface;
+ }
+
+ void OnShellSurfaceDestroyed(ShellSurface* shell_surface) {
+ shell_surfaces_.erase(shell_surface);
}
std::unique_ptr<NotificationSurface> CreateNotificationSurface(
@@ -2060,9 +2095,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
@@ -2092,6 +2138,10 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
}
private:
+ bool IsMultiDisplaySupported() const {
+ return wl_resource_get_version(remote_shell_resource_) >= 3;
+ }
+
void ScheduleSendDisplayMetrics(int delay_ms) {
needs_send_display_metrics_ = true;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
@@ -2108,12 +2158,27 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
const display::Screen* screen = display::Screen::GetScreen();
const display::Display primary_display = screen->GetPrimaryDisplay();
+ gfx::Size size = primary_display.size();
+
+ if (IsMultiDisplaySupported()) {
+ // Virtual screen is the bounding box of the displays in screen
+ // coordinates.
+ gfx::Rect bounds;
+ for (const auto& display : screen->GetAllDisplays())
+ bounds.Union(display.bounds());
+
+ virtual_origin_ = bounds.origin();
+ size = bounds.size();
+
+ for (ShellSurface* shell_surface : shell_surfaces_)
+ shell_surface->SetOrigin(virtual_origin_);
+ }
+
+ // 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_, size.width(), size.height(),
OutputTransform(primary_display.rotation()),
wl_fixed_from_double(primary_display.device_scale_factor()),
work_area_insets.left(), work_area_insets.top(),
@@ -2164,6 +2229,11 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
int layout_mode_ = ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_WINDOWED;
+ // Origin of the virtual screen relative to the primary display.
+ gfx::Point virtual_origin_;
+
+ std::unordered_set<ShellSurface*> shell_surfaces_; // Unowned.
reveman 2017/02/17 01:29:34 As discussed. Please refactor ShellSurface so this
+
base::WeakPtrFactory<WaylandRemoteShell> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(WaylandRemoteShell);
@@ -2221,6 +2291,24 @@ void HandleRemoteSurfaceStateChangedCallback(
wl_client_flush(wl_resource_get_client(resource));
}
+uint32_t HandleRemoteSurfaceConfigureCallback(
+ wl_resource* resource,
+ const gfx::Size& size,
+ ash::wm::WindowStateType state_type,
+ bool resizing,
+ bool activated,
+ const gfx::Point& origin) {
+ wl_array states;
+ wl_array_init(&states);
+ uint32_t serial = wl_display_next_serial(
+ wl_client_get_display(wl_resource_get_client(resource)));
+ zcr_remote_surface_v1_send_configure(resource, origin.x(), origin.y(),
+ &states, serial);
+ wl_client_flush(wl_resource_get_client(resource));
+ wl_array_release(&states);
+ return serial;
+}
+
void remote_shell_get_remote_surface(wl_client* client,
wl_resource* resource,
uint32_t id,
@@ -2245,6 +2333,9 @@ void remote_shell_get_remote_surface(wl_client* client,
shell_surface->set_state_changed_callback(
base::Bind(&HandleRemoteSurfaceStateChangedCallback,
base::Unretained(remote_surface_resource)));
+ shell_surface->set_configure_callback(
+ base::Bind(&HandleRemoteSurfaceConfigureCallback,
+ base::Unretained(remote_surface_resource)));
SetImplementation(remote_surface_resource, &remote_surface_implementation,
std::move(shell_surface));
@@ -2283,7 +2374,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,
« no previous file with comments | « components/exo/shell_surface_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698