Commit 22ec5b51 authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Commit Bot

Reland "Propagate flip layout proprety of the popups"

This reverts commit 6488ecd7.

Reason for revert: the leak was identified in crbug.com/859262,
and same leak happened after this revert.

https://ci.chromium.org/p/chromium/builders/luci.chromium.ci/Linux%20Chromium%20OS%20ASan%20LSan%20Tests%20%281%29/28109

Original change's description:
> Revert "Propagate flip layout proprety of the popups"
> 
> This reverts commit fbe272fb.
> 
> Reason for revert: exo_unittests are flaky on Linux ASan:
> https://ci.chromium.org/p/chromium/builders/luci.chromium.ci/Linux%20Chromium%20OS%20ASan%20LSan%20Tests%20%281%29?limit=200
> 
> Original change's description:
> > Propagate flip layout proprety of the popups
> > 
> > BUG=788782
> > TEST=manully tested with gtk3-demo
> > 
> > Change-Id: I4a381b9350675d4e5407b378fbe07ae9de64fe8a
> > Reviewed-on: https://chromium-review.googlesource.com/1108558
> > Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
> > Reviewed-by: David Reveman <reveman@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#569893}
> 
> TBR=reveman@chromium.org,oshima@chromium.org
> 
> # Not skipping CQ checks because original CL landed > 1 day ago.
> 
> Bug: 788782
> Change-Id: Iae9444d706ff01f37787781955bfbbb8dff63c01
> Reviewed-on: https://chromium-review.googlesource.com/1115918
> Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
> Commit-Queue: Dmitry Gozman <dgozman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#570586}

TBR=dgozman@chromium.org,reveman@chromium.org,oshima@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 788782
Change-Id: Ibb60d892830e070683ac1d8190144d50fa8d876a
Reviewed-on: https://chromium-review.googlesource.com/1122876Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#571909}
parent 43305ab8
......@@ -1382,11 +1382,27 @@ uint32_t InvertBitfield(uint32_t bitfield, uint32_t mask) {
// TODO(oshima): propagate x/y flip state to children.
struct WaylandPositioner {
static constexpr uint32_t kHorizontalAnchors =
ZXDG_POSITIONER_V6_ANCHOR_LEFT | ZXDG_POSITIONER_V6_ANCHOR_RIGHT;
static constexpr uint32_t kVerticalAnchors =
ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_BOTTOM;
static constexpr uint32_t kHorizontalGravities =
ZXDG_POSITIONER_V6_GRAVITY_LEFT | ZXDG_POSITIONER_V6_GRAVITY_RIGHT;
static constexpr uint32_t kVerticalGravities =
ZXDG_POSITIONER_V6_GRAVITY_TOP | ZXDG_POSITIONER_V6_GRAVITY_BOTTOM;
static int CalculateX(const gfx::Size& size,
const gfx::Rect& anchor_rect,
uint32_t anchor,
uint32_t gravity,
int offset) {
int offset,
bool flipped) {
if (flipped) {
anchor = InvertBitfield(anchor, kHorizontalAnchors);
gravity = InvertBitfield(gravity, kHorizontalGravities);
offset = -offset;
}
int x = offset;
if (anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT)
x += anchor_rect.x();
......@@ -1406,7 +1422,14 @@ struct WaylandPositioner {
const gfx::Rect& anchor_rect,
uint32_t anchor,
uint32_t gravity,
int offset) {
int offset,
bool flipped) {
if (flipped) {
anchor = InvertBitfield(anchor, kVerticalAnchors);
gravity = InvertBitfield(gravity, kVerticalGravities);
offset = -offset;
}
int y = offset;
if (anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP)
y += anchor_rect.y();
......@@ -1423,22 +1446,14 @@ struct WaylandPositioner {
}
// Calculate and return position from current state.
gfx::Point CalculatePosition(const gfx::Rect& work_area) const {
constexpr uint32_t kHorizontalAnchors =
ZXDG_POSITIONER_V6_ANCHOR_LEFT | ZXDG_POSITIONER_V6_ANCHOR_RIGHT;
constexpr uint32_t kVerticalAnchors =
ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_BOTTOM;
constexpr uint32_t kHorizontalGravities =
ZXDG_POSITIONER_V6_GRAVITY_LEFT | ZXDG_POSITIONER_V6_GRAVITY_RIGHT;
constexpr uint32_t kVerticalGravities =
ZXDG_POSITIONER_V6_GRAVITY_TOP | ZXDG_POSITIONER_V6_GRAVITY_BOTTOM;
gfx::Point CalculatePosition(const gfx::Rect& work_area) {
// TODO(oshima): The size must be smaller than work area.
gfx::Rect bounds(
gfx::Point(CalculateX(size, anchor_rect, anchor, gravity, offset.x()),
CalculateY(size, anchor_rect, anchor, gravity, offset.y())),
size);
gfx::Rect bounds(gfx::Point(CalculateX(size, anchor_rect, anchor, gravity,
offset.x(), x_flipped),
CalculateY(size, anchor_rect, anchor, gravity,
offset.y(), y_flipped)),
size);
// Adjust x position if the bounds are not fully contained by the work area.
if (work_area.x() > bounds.x() || work_area.right() < bounds.right()) {
......@@ -1455,9 +1470,9 @@ struct WaylandPositioner {
else if (bounds.right() > work_area.right())
bounds.set_x(work_area.right() - size.width());
} else if (adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X) {
bounds.set_x(CalculateX(
size, anchor_rect, InvertBitfield(anchor, kHorizontalAnchors),
InvertBitfield(gravity, kHorizontalGravities), -offset.x()));
x_flipped = !x_flipped;
bounds.set_x(CalculateX(size, anchor_rect, anchor, gravity, offset.x(),
x_flipped));
}
}
......@@ -1476,9 +1491,9 @@ struct WaylandPositioner {
else if (bounds.bottom() > work_area.bottom())
bounds.set_y(work_area.bottom() - size.height());
} else if (adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y) {
bounds.set_y(CalculateY(
size, anchor_rect, InvertBitfield(anchor, kVerticalAnchors),
InvertBitfield(gravity, kVerticalGravities), -offset.y()));
y_flipped = !y_flipped;
bounds.set_y(CalculateY(size, anchor_rect, anchor, gravity, offset.y(),
y_flipped));
}
}
return bounds.origin();
......@@ -1490,6 +1505,8 @@ struct WaylandPositioner {
uint32_t gravity = ZXDG_POSITIONER_V6_GRAVITY_NONE;
uint32_t adjustment = ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE;
gfx::Vector2d offset;
bool y_flipped = false;
bool x_flipped = false;
};
void xdg_positioner_v6_destroy(wl_client* client, wl_resource* resource) {
......@@ -1974,7 +1991,7 @@ void xdg_surface_v6_get_popup(wl_client* client,
return;
}
ShellSurface* parent = GetUserDataAs<ShellSurface>(parent_resource);
XdgShellSurface* parent = GetUserDataAs<XdgShellSurface>(parent_resource);
if (!parent->GetWidget()) {
wl_resource_post_error(resource, ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
"popup parent not constructed");
......@@ -1986,14 +2003,25 @@ void xdg_surface_v6_get_popup(wl_client* client,
"get_popup is called after constructed");
return;
}
display::Display display =
display::Screen::GetScreen()->GetDisplayNearestWindow(
parent->GetWidget()->GetNativeWindow());
gfx::Rect work_area = display.work_area();
wm::ConvertRectFromScreen(parent->GetWidget()->GetNativeWindow(), &work_area);
gfx::Point position = GetUserDataAs<WaylandPositioner>(positioner_resource)
->CalculatePosition(work_area);
WaylandPositioner* positioner =
GetUserDataAs<WaylandPositioner>(positioner_resource);
// Try layout using parent's flip state.
positioner->x_flipped = parent->x_flipped();
positioner->y_flipped = parent->y_flipped();
gfx::Point position = positioner->CalculatePosition(work_area);
// Remember the new flip state for its child popups.
shell_surface->set_x_flipped(positioner->x_flipped);
shell_surface->set_y_flipped(positioner->y_flipped);
// |position| is relative to the parent's contents view origin, and |origin|
// is in screen coordinates.
gfx::Point origin = position;
......
......@@ -50,7 +50,18 @@ class XdgShellSurface : public ShellSurface {
int container);
~XdgShellSurface() override;
bool x_flipped() const { return x_flipped_; }
void set_x_flipped(bool flipped) { x_flipped_ = flipped; }
bool y_flipped() const { return y_flipped_; }
void set_y_flipped(bool flipped) { y_flipped_ = flipped; }
private:
// Used by positioner to layout cascading menus in opposite
// direction when the layout does not fit to the work area.
bool y_flipped_ = false;
bool x_flipped_ = false;
DISALLOW_COPY_AND_ASSIGN(XdgShellSurface);
};
......
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