Commit 677d9287 authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Commit Bot

exo: Add extensions to WaylandDisplayObserver

We add extensions to WaylandDisplayObserver called
WaylandDisplayObserverExtensions that allow display information to be
sent through other protocols and be followed by a wl_output "done"
event.

WaylandDisplayObserver only reported scale changes to its observers.
Since remote_output needs to know about work area changes as well as
scale changes, we modify WaylandDisplayObserver to report all metrics
changes to its extensions, which can decide if it needs to send any
updates.

BUG=b:165094142
TEST=exo_unittests
TEST=Verify insets are updated in ARC++.

Change-Id: I6577fe15eb5b09527008cf69a26b5eec7a7f1374
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2363481Reviewed-by: default avatarJun Mukai <mukai@chromium.org>
Commit-Queue: Prabir Pradhan <prabirmsp@chromium.org>
Auto-Submit: Prabir Pradhan <prabirmsp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800229}
parent 34cb7e79
...@@ -16,50 +16,74 @@ ...@@ -16,50 +16,74 @@
namespace exo { namespace exo {
namespace wayland { namespace wayland {
WaylandDisplayObserver::WaylandDisplayObserver(WaylandDisplayOutput* output, WaylandDisplayHandler::WaylandDisplayHandler(WaylandDisplayOutput* output,
wl_resource* output_resource) wl_resource* output_resource)
: output_(output), output_resource_(output_resource) { : output_(output), output_resource_(output_resource) {
output_->RegisterOutput(output_resource_); output_->RegisterOutput(output_resource_);
display::Screen::GetScreen()->AddObserver(this); display::Screen::GetScreen()->AddObserver(this);
SendDisplayMetrics();
// Adding itself as an observer will send the initial display metrics.
AddObserver(this);
} }
WaylandDisplayObserver::~WaylandDisplayObserver() { WaylandDisplayHandler::~WaylandDisplayHandler() {
output_->UnregisterOutput(output_resource_); output_->UnregisterOutput(output_resource_);
display::Screen::GetScreen()->RemoveObserver(this); display::Screen::GetScreen()->RemoveObserver(this);
} }
void WaylandDisplayObserver::AddScaleObserver(ScaleObserver* scale_observer) { void WaylandDisplayHandler::AddObserver(WaylandDisplayObserver* observer) {
scale_observers_.AddObserver(scale_observer); observers_.AddObserver(observer);
SendDisplayMetrics();
display::Display display;
bool rv = display::Screen::GetScreen()->GetDisplayWithDisplayId(output_->id(),
&display);
DCHECK(rv);
// Send the first round of changes to the observer.
constexpr uint32_t all_changes = 0xFFFFFFFF;
if (observer->SendDisplayMetrics(display, all_changes)) {
if (wl_resource_get_version(output_resource_) >=
WL_OUTPUT_DONE_SINCE_VERSION) {
wl_output_send_done(output_resource_);
}
wl_client_flush(wl_resource_get_client(output_resource_));
}
} }
void WaylandDisplayObserver::OnDisplayMetricsChanged( void WaylandDisplayHandler::OnDisplayMetricsChanged(
const display::Display& display, const display::Display& display,
uint32_t changed_metrics) { uint32_t changed_metrics) {
if (output_->id() != display.id()) if (output_->id() != display.id())
return; return;
bool needs_done = false;
for (auto& observer : observers_)
needs_done |= observer.SendDisplayMetrics(display, changed_metrics);
if (needs_done) {
if (wl_resource_get_version(output_resource_) >=
WL_OUTPUT_DONE_SINCE_VERSION) {
wl_output_send_done(output_resource_);
}
wl_client_flush(wl_resource_get_client(output_resource_));
}
}
bool WaylandDisplayHandler::SendDisplayMetrics(const display::Display& display,
uint32_t changed_metrics) {
// There is no need to check DISPLAY_METRIC_PRIMARY because when primary // There is no need to check DISPLAY_METRIC_PRIMARY because when primary
// changes, bounds always changes. (new primary should have had non // changes, bounds always changes. (new primary should have had non
// 0,0 origin). // 0,0 origin).
// Only exception is when switching to newly connected primary with // Only exception is when switching to newly connected primary with
// the same bounds. This happens whenyou're in docked mode, suspend, // the same bounds. This happens whenyou're in docked mode, suspend,
// unplug the dislpay, then resume to the internal display which has // unplug the display, then resume to the internal display which has
// the same resolution. Since metrics does not change, there is no need // the same resolution. Since metrics does not change, there is no need
// to notify clients. // to notify clients.
if (changed_metrics & if (!(changed_metrics &
(DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_DEVICE_SCALE_FACTOR | (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_DEVICE_SCALE_FACTOR |
DISPLAY_METRIC_ROTATION)) { DISPLAY_METRIC_ROTATION))) {
SendDisplayMetrics(); return false;
} }
}
void WaylandDisplayObserver::SendDisplayMetrics() {
display::Display display;
bool rv = display::Screen::GetScreen()->GetDisplayWithDisplayId(output_->id(),
&display);
DCHECK(rv);
const display::ManagedDisplayInfo& info = const display::ManagedDisplayInfo& info =
WMHelper::GetInstance()->GetDisplayInfo(display.id()); WMHelper::GetInstance()->GetDisplayInfo(display.id());
...@@ -99,18 +123,10 @@ void WaylandDisplayObserver::SendDisplayMetrics() { ...@@ -99,18 +123,10 @@ void WaylandDisplayObserver::SendDisplayMetrics() {
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
bounds.width(), bounds.height(), static_cast<int>(60000)); bounds.width(), bounds.height(), static_cast<int>(60000));
for (auto& observer : scale_observers_) return true;
observer.OnDisplayScalesChanged(display);
if (wl_resource_get_version(output_resource_) >=
WL_OUTPUT_DONE_SINCE_VERSION) {
wl_output_send_done(output_resource_);
}
wl_client_flush(wl_resource_get_client(output_resource_));
} }
wl_output_transform WaylandDisplayObserver::OutputTransform( wl_output_transform WaylandDisplayHandler::OutputTransform(
display::Display::Rotation rotation) { display::Display::Rotation rotation) {
// Note: |rotation| describes the counter clockwise rotation that a // Note: |rotation| describes the counter clockwise rotation that a
// display's output is currently adjusted for, which is the inverse // display's output is currently adjusted for, which is the inverse
......
...@@ -18,30 +18,39 @@ namespace exo { ...@@ -18,30 +18,39 @@ namespace exo {
namespace wayland { namespace wayland {
class WaylandDisplayOutput; class WaylandDisplayOutput;
class WaylandDisplayObserver : public display::DisplayObserver { // An observer that allows display information changes to be sent
// via different protocols while being synced with the wl_output's
// "done" event through WaylandDisplayHandler.
class WaylandDisplayObserver : public base::CheckedObserver {
public: public:
class ScaleObserver : public base::CheckedObserver { WaylandDisplayObserver() {}
public:
ScaleObserver() {}
virtual void OnDisplayScalesChanged(const display::Display& display) = 0; // Returns |true| if the observer reported any changes and needs
// to be followed by "done" event, |false| otherwise.
virtual bool SendDisplayMetrics(const display::Display& display,
uint32_t changed_metrics) = 0;
protected: protected:
~ScaleObserver() override {} ~WaylandDisplayObserver() override {}
}; };
WaylandDisplayObserver(WaylandDisplayOutput* output, class WaylandDisplayHandler : public display::DisplayObserver,
public WaylandDisplayObserver {
public:
WaylandDisplayHandler(WaylandDisplayOutput* output,
wl_resource* output_resource); wl_resource* output_resource);
~WaylandDisplayObserver() override; ~WaylandDisplayHandler() override;
void AddScaleObserver(ScaleObserver* scale_observer); void AddObserver(WaylandDisplayObserver* observer);
bool HasScaleObserver(ScaleObserver* scale_observer) const;
// Overridden from display::DisplayObserver: // Overridden from display::DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display, void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override; uint32_t changed_metrics) override;
private: private:
void SendDisplayMetrics(); // Overridden from WaylandDisplayObserver:
bool SendDisplayMetrics(const display::Display& display,
uint32_t changed_metrics) override;
// Returns the transform that a compositor will apply to a surface to // Returns the transform that a compositor will apply to a surface to
// compensate for the rotation of an output device. // compensate for the rotation of an output device.
wl_output_transform OutputTransform(display::Display::Rotation rotation); wl_output_transform OutputTransform(display::Display::Rotation rotation);
...@@ -52,9 +61,9 @@ class WaylandDisplayObserver : public display::DisplayObserver { ...@@ -52,9 +61,9 @@ class WaylandDisplayObserver : public display::DisplayObserver {
// The output resource associated with the display. // The output resource associated with the display.
wl_resource* const output_resource_; wl_resource* const output_resource_;
base::ObserverList<ScaleObserver> scale_observers_; base::ObserverList<WaylandDisplayObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(WaylandDisplayObserver); DISALLOW_COPY_AND_ASSIGN(WaylandDisplayHandler);
}; };
} // namespace wayland } // namespace wayland
......
...@@ -38,7 +38,7 @@ void bind_output(wl_client* client, ...@@ -38,7 +38,7 @@ void bind_output(wl_client* client,
wl_resource_create(client, &wl_output_interface, wl_resource_create(client, &wl_output_interface,
std::min(version, kWlOutputVersion), output_id); std::min(version, kWlOutputVersion), output_id);
SetImplementation(resource, &output_implementation, SetImplementation(resource, &output_implementation,
std::make_unique<WaylandDisplayObserver>(output, resource)); std::make_unique<WaylandDisplayHandler>(output, resource));
} }
} // namespace wayland } // namespace wayland
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "components/exo/wm_helper.h" #include "components/exo/wm_helper.h"
#include "ui/aura/env.h" #include "ui/aura/env.h"
#include "ui/aura/window_occlusion_tracker.h" #include "ui/aura/window_occlusion_tracker.h"
#include "ui/display/display_observer.h"
#include "ui/display/manager/display_manager.h" #include "ui/display/manager/display_manager.h"
#include "ui/display/manager/display_util.h" #include "ui/display/manager/display_util.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
...@@ -373,12 +374,20 @@ namespace { ...@@ -373,12 +374,20 @@ namespace {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// aura_output_interface: // aura_output_interface:
class AuraOutput : public WaylandDisplayObserver::ScaleObserver { class AuraOutput : public WaylandDisplayObserver {
public: public:
explicit AuraOutput(wl_resource* resource) : resource_(resource) {} explicit AuraOutput(wl_resource* resource) : resource_(resource) {}
// Overridden from WaylandDisplayObserver::ScaleObserver: // Overridden from WaylandDisplayObserver:
void OnDisplayScalesChanged(const display::Display& display) override { bool SendDisplayMetrics(const display::Display& display,
uint32_t changed_metrics) override {
if (!(changed_metrics &
(display::DisplayObserver::DISPLAY_METRIC_BOUNDS |
display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR |
display::DisplayObserver::DISPLAY_METRIC_ROTATION))) {
return false;
}
const WMHelper* wm_helper = WMHelper::GetInstance(); const WMHelper* wm_helper = WMHelper::GetInstance();
const display::ManagedDisplayInfo& display_info = const display::ManagedDisplayInfo& display_info =
wm_helper->GetDisplayInfo(display.id()); wm_helper->GetDisplayInfo(display.id());
...@@ -434,6 +443,8 @@ class AuraOutput : public WaylandDisplayObserver::ScaleObserver { ...@@ -434,6 +443,8 @@ class AuraOutput : public WaylandDisplayObserver::ScaleObserver {
zaura_output_send_device_scale_factor( zaura_output_send_device_scale_factor(
resource_, display_info.device_scale_factor() * 1000); resource_, display_info.device_scale_factor() * 1000);
} }
return true;
} }
private: private:
...@@ -469,14 +480,14 @@ void aura_shell_get_aura_output(wl_client* client, ...@@ -469,14 +480,14 @@ void aura_shell_get_aura_output(wl_client* client,
wl_resource* resource, wl_resource* resource,
uint32_t id, uint32_t id,
wl_resource* output_resource) { wl_resource* output_resource) {
WaylandDisplayObserver* display_observer = WaylandDisplayHandler* display_handler =
GetUserDataAs<WaylandDisplayObserver>(output_resource); GetUserDataAs<WaylandDisplayHandler>(output_resource);
wl_resource* aura_output_resource = wl_resource_create( wl_resource* aura_output_resource = wl_resource_create(
client, &zaura_output_interface, wl_resource_get_version(resource), id); client, &zaura_output_interface, wl_resource_get_version(resource), id);
auto aura_output = std::make_unique<AuraOutput>(aura_output_resource); auto aura_output = std::make_unique<AuraOutput>(aura_output_resource);
display_observer->AddScaleObserver(aura_output.get()); display_handler->AddObserver(aura_output.get());
SetImplementation(aura_output_resource, nullptr, std::move(aura_output)); SetImplementation(aura_output_resource, nullptr, std::move(aura_output));
} }
......
...@@ -742,14 +742,21 @@ const struct zcr_remote_output_v1_interface remote_output_implementation = { ...@@ -742,14 +742,21 @@ const struct zcr_remote_output_v1_interface remote_output_implementation = {
remote_output_destroy, remote_output_destroy,
}; };
class WaylandRemoteOutput : public WaylandDisplayObserver::ScaleObserver { class WaylandRemoteOutput : public WaylandDisplayObserver {
public: public:
explicit WaylandRemoteOutput(wl_resource* resource) : resource_(resource) {} explicit WaylandRemoteOutput(wl_resource* resource) : resource_(resource) {}
// Overridden from WaylandDisplayObserver::ScaleObserver: // Overridden from WaylandDisplayObserver:
void OnDisplayScalesChanged(const display::Display& display) override { bool SendDisplayMetrics(const display::Display& display,
uint32_t changed_metrics) override {
if (wl_resource_get_version(resource_) < 29) if (wl_resource_get_version(resource_) < 29)
return; return false;
if (initial_config_sent_ &&
!(changed_metrics &
display::DisplayObserver::DISPLAY_METRIC_WORK_AREA)) {
return false;
}
if (!initial_config_sent_) { if (!initial_config_sent_) {
initial_config_sent_ = true; initial_config_sent_ = true;
...@@ -803,6 +810,8 @@ class WaylandRemoteOutput : public WaylandDisplayObserver::ScaleObserver { ...@@ -803,6 +810,8 @@ class WaylandRemoteOutput : public WaylandDisplayObserver::ScaleObserver {
: ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_VISIBLE; : ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_VISIBLE;
zcr_remote_output_v1_send_systemui_visibility(resource_, zcr_remote_output_v1_send_systemui_visibility(resource_,
systemui_visibility); systemui_visibility);
return true;
} }
private: private:
...@@ -1470,8 +1479,8 @@ void remote_shell_get_remote_output(wl_client* client, ...@@ -1470,8 +1479,8 @@ void remote_shell_get_remote_output(wl_client* client,
wl_resource* resource, wl_resource* resource,
uint32_t id, uint32_t id,
wl_resource* output_resource) { wl_resource* output_resource) {
WaylandDisplayObserver* display_observer = WaylandDisplayHandler* display_handler =
GetUserDataAs<WaylandDisplayObserver>(output_resource); GetUserDataAs<WaylandDisplayHandler>(output_resource);
wl_resource* remote_output_resource = wl_resource* remote_output_resource =
wl_resource_create(client, &zcr_remote_output_v1_interface, wl_resource_create(client, &zcr_remote_output_v1_interface,
...@@ -1479,7 +1488,7 @@ void remote_shell_get_remote_output(wl_client* client, ...@@ -1479,7 +1488,7 @@ void remote_shell_get_remote_output(wl_client* client,
auto remote_output = auto remote_output =
std::make_unique<WaylandRemoteOutput>(remote_output_resource); std::make_unique<WaylandRemoteOutput>(remote_output_resource);
display_observer->AddScaleObserver(remote_output.get()); display_handler->AddObserver(remote_output.get());
SetImplementation(remote_output_resource, &remote_output_implementation, SetImplementation(remote_output_resource, &remote_output_implementation,
std::move(remote_output)); std::move(remote_output));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment