diff options
Diffstat (limited to 'chromium/components/exo/wayland/wayland_positioner.cc')
-rw-r--r-- | chromium/components/exo/wayland/wayland_positioner.cc | 199 |
1 files changed, 159 insertions, 40 deletions
diff --git a/chromium/components/exo/wayland/wayland_positioner.cc b/chromium/components/exo/wayland/wayland_positioner.cc index 625fad4a5e8..65b9ec694e0 100644 --- a/chromium/components/exo/wayland/wayland_positioner.cc +++ b/chromium/components/exo/wayland/wayland_positioner.cc @@ -4,28 +4,129 @@ #include "components/exo/wayland/wayland_positioner.h" +#include <xdg-shell-unstable-v6-server-protocol.h> + namespace exo { namespace wayland { namespace { -// Represents the 1-dimensional projection of the gravity/anchor values. -enum Direction { kNegative = -1, kNeutral = 0, kPositive = 1 }; +std::pair<WaylandPositioner::Direction, WaylandPositioner::Direction> +DecomposeUnstableAnchor(uint32_t anchor) { + WaylandPositioner::Direction x, y; + + if (anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT) { + x = WaylandPositioner::Direction::kNegative; + } else if (anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT) { + x = WaylandPositioner::Direction::kPositive; + } else { + x = WaylandPositioner::Direction::kNeutral; + } + + if (anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP) { + y = WaylandPositioner::Direction::kNegative; + } else if (anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM) { + y = WaylandPositioner::Direction::kPositive; + } else { + y = WaylandPositioner::Direction::kNeutral; + } + + return std::make_pair(x, y); +} + +std::pair<WaylandPositioner::Direction, WaylandPositioner::Direction> +DecomposeStableAnchor(uint32_t anchor) { + switch (anchor) { + default: + case XDG_POSITIONER_ANCHOR_NONE: + return std::make_pair(WaylandPositioner::Direction::kNeutral, + WaylandPositioner::Direction::kNeutral); + case XDG_POSITIONER_ANCHOR_TOP: + return std::make_pair(WaylandPositioner::Direction::kNeutral, + WaylandPositioner::Direction::kNegative); + case XDG_POSITIONER_ANCHOR_BOTTOM: + return std::make_pair(WaylandPositioner::Direction::kNeutral, + WaylandPositioner::Direction::kPositive); + case XDG_POSITIONER_ANCHOR_LEFT: + return std::make_pair(WaylandPositioner::Direction::kNegative, + WaylandPositioner::Direction::kNeutral); + case XDG_POSITIONER_ANCHOR_RIGHT: + return std::make_pair(WaylandPositioner::Direction::kPositive, + WaylandPositioner::Direction::kNeutral); + case XDG_POSITIONER_ANCHOR_TOP_LEFT: + return std::make_pair(WaylandPositioner::Direction::kNegative, + WaylandPositioner::Direction::kNegative); + case XDG_POSITIONER_ANCHOR_TOP_RIGHT: + return std::make_pair(WaylandPositioner::Direction::kPositive, + WaylandPositioner::Direction::kNegative); + case XDG_POSITIONER_ANCHOR_BOTTOM_LEFT: + return std::make_pair(WaylandPositioner::Direction::kNegative, + WaylandPositioner::Direction::kPositive); + case XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT: + return std::make_pair(WaylandPositioner::Direction::kPositive, + WaylandPositioner::Direction::kPositive); + } +} + +std::pair<WaylandPositioner::Direction, WaylandPositioner::Direction> +DecomposeUnstableGravity(uint32_t gravity) { + WaylandPositioner::Direction x, y; + + if (gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT) { + x = WaylandPositioner::Direction::kNegative; + } else if (gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT) { + x = WaylandPositioner::Direction::kPositive; + } else { + x = WaylandPositioner::Direction::kNeutral; + } + + if (gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP) { + y = WaylandPositioner::Direction::kNegative; + } else if (gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM) { + y = WaylandPositioner::Direction::kPositive; + } else { + y = WaylandPositioner::Direction::kNeutral; + } -static Direction Flip(Direction d) { - return (Direction)-d; + return std::make_pair(x, y); +} + +std::pair<WaylandPositioner::Direction, WaylandPositioner::Direction> +DecomposeStableGravity(uint32_t gravity) { + switch (gravity) { + default: + case XDG_POSITIONER_GRAVITY_NONE: + return std::make_pair(WaylandPositioner::Direction::kNeutral, + WaylandPositioner::Direction::kNeutral); + case XDG_POSITIONER_GRAVITY_TOP: + return std::make_pair(WaylandPositioner::Direction::kNeutral, + WaylandPositioner::Direction::kNegative); + case XDG_POSITIONER_GRAVITY_BOTTOM: + return std::make_pair(WaylandPositioner::Direction::kNeutral, + WaylandPositioner::Direction::kPositive); + case XDG_POSITIONER_GRAVITY_LEFT: + return std::make_pair(WaylandPositioner::Direction::kNegative, + WaylandPositioner::Direction::kNeutral); + case XDG_POSITIONER_GRAVITY_RIGHT: + return std::make_pair(WaylandPositioner::Direction::kPositive, + WaylandPositioner::Direction::kNeutral); + case XDG_POSITIONER_GRAVITY_TOP_LEFT: + return std::make_pair(WaylandPositioner::Direction::kNegative, + WaylandPositioner::Direction::kNegative); + case XDG_POSITIONER_GRAVITY_TOP_RIGHT: + return std::make_pair(WaylandPositioner::Direction::kPositive, + WaylandPositioner::Direction::kNegative); + case XDG_POSITIONER_GRAVITY_BOTTOM_LEFT: + return std::make_pair(WaylandPositioner::Direction::kNegative, + WaylandPositioner::Direction::kPositive); + case XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT: + return std::make_pair(WaylandPositioner::Direction::kPositive, + WaylandPositioner::Direction::kPositive); + } } -// Decodes a masked anchor/gravity bitfield to the direction. -Direction MaskToDirection(uint32_t field, - uint32_t negative_mask, - uint32_t positive_mask) { - DCHECK(!((field & negative_mask) && (field & positive_mask))); - if (field & negative_mask) - return kNegative; - if (field & positive_mask) - return kPositive; - return kNeutral; +static WaylandPositioner::Direction Flip(WaylandPositioner::Direction d) { + return (WaylandPositioner::Direction)-d; } // Represents the possible/actual positioner adjustments for this window. @@ -63,8 +164,8 @@ Range1D Calculate(const ConstraintAdjustment& adjustments, Range1D anchor_range, uint32_t size, int32_t offset, - Direction anchor, - Direction gravity) { + WaylandPositioner::Direction anchor, + WaylandPositioner::Direction gravity) { if (adjustments.flip) { return Calculate({/*flip=*/false, adjustments.slide, adjustments.resize}, work_size, anchor_range, size, -offset, Flip(anchor), @@ -91,25 +192,25 @@ Range1D Calculate(const ConstraintAdjustment& adjustments, int32_t start = offset; switch (anchor) { - case Direction::kNegative: + case WaylandPositioner::Direction::kNegative: start += anchor_range.start; break; - case Direction::kNeutral: + case WaylandPositioner::Direction::kNeutral: start += anchor_range.center(); break; - case Direction::kPositive: + case WaylandPositioner::Direction::kPositive: start += anchor_range.end; break; } switch (gravity) { - case Direction::kNegative: + case WaylandPositioner::Direction::kNegative: start -= size; break; - case Direction::kNeutral: + case WaylandPositioner::Direction::kNeutral: start -= size / 2; break; - case Direction::kPositive: + case WaylandPositioner::Direction::kPositive: break; } return {start, start + size}; @@ -124,8 +225,8 @@ std::pair<Range1D, ConstraintAdjustment> DetermineBestConstraintAdjustment( const Range1D& anchor_range, uint32_t size, int32_t offset, - Direction anchor, - Direction gravity, + WaylandPositioner::Direction anchor, + WaylandPositioner::Direction gravity, const ConstraintAdjustment& valid_adjustments) { if (work_area.start != 0) { int32_t shift = -work_area.start; @@ -174,29 +275,47 @@ std::pair<Range1D, ConstraintAdjustment> DetermineBestConstraintAdjustment( } // namespace +void WaylandPositioner::SetAnchor(uint32_t anchor) { + std::pair<WaylandPositioner::Direction, WaylandPositioner::Direction> + decompose; + if (version_ == UNSTABLE) { + decompose = DecomposeUnstableAnchor(anchor); + } else { + decompose = DecomposeStableAnchor(anchor); + } + anchor_x_ = decompose.first; + anchor_y_ = decompose.second; +} + +void WaylandPositioner::SetGravity(uint32_t gravity) { + std::pair<WaylandPositioner::Direction, WaylandPositioner::Direction> + decompose; + if (version_ == UNSTABLE) { + decompose = DecomposeUnstableGravity(gravity); + } else { + decompose = DecomposeStableGravity(gravity); + } + gravity_x_ = decompose.first; + gravity_y_ = decompose.second; +} + WaylandPositioner::Result WaylandPositioner::CalculatePosition( const gfx::Rect& work_area, bool flip_x, bool flip_y) const { - Direction anchor_x = MaskToDirection(anchor_, ZXDG_POSITIONER_V6_ANCHOR_LEFT, - ZXDG_POSITIONER_V6_ANCHOR_RIGHT); - Direction anchor_y = MaskToDirection(anchor_, ZXDG_POSITIONER_V6_ANCHOR_TOP, - ZXDG_POSITIONER_V6_ANCHOR_BOTTOM); - Direction gravity_x = - MaskToDirection(gravity_, ZXDG_POSITIONER_V6_GRAVITY_LEFT, - ZXDG_POSITIONER_V6_GRAVITY_RIGHT); - Direction gravity_y = - MaskToDirection(gravity_, ZXDG_POSITIONER_V6_GRAVITY_TOP, - ZXDG_POSITIONER_V6_GRAVITY_BOTTOM); + auto anchor_x = anchor_x_; + auto anchor_y = anchor_y_; + auto gravity_x = gravity_x_; + auto gravity_y = gravity_y_; ConstraintAdjustment adjustments_x = MaskToConstraintAdjustment( - adjustment_, ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X, - ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X, - ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X); + adjustment_, XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X, + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X, + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X); ConstraintAdjustment adjustments_y = MaskToConstraintAdjustment( - adjustment_, ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y, - ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y, - ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y); + adjustment_, XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y, + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y, + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y); int32_t offset_x = offset_.x(); int32_t offset_y = offset_.y(); |