summaryrefslogtreecommitdiff
path: root/chromium/ui/ozone/platform
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/ozone/platform')
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_screen.cc10
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_surface.cc32
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_window.cc16
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_window.h9
4 files changed, 44 insertions, 23 deletions
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_screen.cc b/chromium/ui/ozone/platform/wayland/host/wayland_screen.cc
index 241b037b5b3..54fb4cf6487 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_screen.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_screen.cc
@@ -129,7 +129,15 @@ void WaylandScreen::OnOutputRemoved(uint32_t output_id) {
}
}
}
- display_list_.RemoveDisplay(output_id);
+ // TODO(https://crbug.com/1299403): Work around the symptoms of a common
+ // crash. Unclear if this is the proper long term solution.
+ auto it = display_list_.FindDisplayById(output_id);
+ DCHECK(it != display_list_.displays().end());
+ if (it != display_list_.displays().end()) {
+ display_list_.RemoveDisplay(output_id);
+ } else {
+ LOG(ERROR) << "output_id is not associated with a Display.";
+ }
}
void WaylandScreen::AddOrUpdateDisplay(uint32_t output_id,
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_surface.cc b/chromium/ui/ozone/platform/wayland/host/wayland_surface.cc
index 0ff844dda1d..43e6152cc2b 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_surface.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_surface.cc
@@ -26,6 +26,7 @@
#include "ui/ozone/platform/wayland/host/wayland_buffer_handle.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_output.h"
+#include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
#include "ui/ozone/platform/wayland/host/wayland_subsurface.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h"
@@ -681,10 +682,15 @@ void WaylandSurface::Enter(void* data,
auto* wayland_output =
static_cast<WaylandOutput*>(wl_output_get_user_data(output));
+
+ DCHECK_NE(surface->connection_->wayland_output_manager()->GetOutput(
+ wayland_output->output_id()),
+ nullptr);
+
surface->entered_outputs_.emplace_back(wayland_output->output_id());
if (surface->root_window_)
- surface->root_window_->OnEnteredOutputIdAdded();
+ surface->root_window_->OnEnteredOutput();
}
// static
@@ -700,27 +706,21 @@ void WaylandSurface::Leave(void* data,
}
void WaylandSurface::RemoveEnteredOutput(uint32_t output_id) {
- if (entered_outputs().empty())
- return;
-
auto entered_outputs_it_ =
std::find_if(entered_outputs_.begin(), entered_outputs_.end(),
[&output_id](uint32_t id) { return id == output_id; });
+ if (entered_outputs_it_ == entered_outputs_.end())
+ return;
- // The `entered_outputs_` list should be updated,
- // 1. for wl_surface::leave, when a user switches physical output between two
- // displays, a surface does not necessarily receive enter events immediately
- // or until a user resizes/moves it. This means that switching output between
- // displays in a single output mode results in leave events, but the surface
- // might not have received enter event before. Thus, remove the id of the
- // output that the surface leaves only if it was stored before.
- // 2. for wl_registry::global_remove, when wl_output is removed by a server
- // after the display is unplugged or switched off.
- if (entered_outputs_it_ != entered_outputs_.end())
- entered_outputs_.erase(entered_outputs_it_);
+ // In certain use cases, such as switching outputs in the single output
+ // configuration, the compositor may move the surface from one output to
+ // another one, send wl_surface::leave event to it, but defer sending
+ // wl_surface::enter until the user moves or resizes the surface on the new
+ // output.
+ entered_outputs_.erase(entered_outputs_it_);
if (root_window_)
- root_window_->OnEnteredOutputIdRemoved();
+ root_window_->OnLeftOutput();
}
void WaylandSurface::SetOverlayPriority(
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_window.cc b/chromium/ui/ozone/platform/wayland/host/wayland_window.cc
index 273f4b514ad..bbfbb210c53 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_window.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -175,6 +175,18 @@ uint32_t WaylandWindow::GetPreferredEnteredOutputId() {
auto* output_manager = connection_->wayland_output_manager();
auto* output = output_manager->GetOutput(output_id);
auto* preferred_output = output_manager->GetOutput(preferred_output_id);
+ // The compositor may have told the surface to enter the output that the
+ // client is not aware of. In such an event, we cannot evaluate scales, and
+ // can only return the default, which means falling back to the primary
+ // display in the code that calls this.
+ // DCHECKS below are kept for trying to catch the situation in developer's
+ // builds and find the way to reproduce the issue.
+ // See crbug.com/1323635
+ DCHECK(output) << " output " << output_id << " not found!";
+ DCHECK(preferred_output)
+ << " output " << preferred_output_id << " not found!";
+ if (!output || !preferred_output)
+ return 0;
if (output->scale_factor() > preferred_output->scale_factor())
preferred_output_id = output_id;
}
@@ -632,7 +644,7 @@ WaylandWindow* WaylandWindow::GetRootParentWindow() {
return parent_window_ ? parent_window_->GetRootParentWindow() : this;
}
-void WaylandWindow::OnEnteredOutputIdAdded() {
+void WaylandWindow::OnEnteredOutput() {
// Wayland does weird things for menus so instead of tracking outputs that
// we entered or left, we take that from the parent window and ignore this
// event.
@@ -642,7 +654,7 @@ void WaylandWindow::OnEnteredOutputIdAdded() {
UpdateWindowScale(true);
}
-void WaylandWindow::OnEnteredOutputIdRemoved() {
+void WaylandWindow::OnLeftOutput() {
// Wayland does weird things for menus so instead of tracking outputs that
// we entered or left, we take that from the parent window and ignore this
// event.
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_window.h b/chromium/ui/ozone/platform/wayland/host/wayland_window.h
index 52472f360ae..5eb89b3917a 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_window.h
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_window.h
@@ -278,12 +278,13 @@ class WaylandWindow : public PlatformWindow,
WaylandWindow* GetTopMostChildWindow();
// Called by the WaylandSurface attached to this window when that surface
- // becomes partially or fully within the scanout region of |output|.
- void OnEnteredOutputIdAdded();
+ // becomes partially or fully within the scanout region of an output that it
+ // wasn't before.
+ void OnEnteredOutput();
// Called by the WaylandSurface attached to this window when that surface
- // becomes fully outside of the scanout region of |output|.
- void OnEnteredOutputIdRemoved();
+ // becomes fully outside of one of outputs that it previously resided on.
+ void OnLeftOutput();
// Returns true iff this window is opaque.
bool IsOpaqueWindow() const;