blob: 4ee425c60e941c1f1de43e8ad3250867547c23a8 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_COLLISION_DETECTION_COLLISION_DETECTION_UTILS_H_
#define ASH_WM_COLLISION_DETECTION_COLLISION_DETECTION_UTILS_H_
#include "ash/ash_export.h"
#include "ui/aura/window.h"
#include "ui/display/display.h"
#include "ui/gfx/geometry/rect.h"
namespace ash {
// The inset into the work area for a window's resting position. Visible for
// testing.
const static int kCollisionWindowWorkAreaInsetsDp = 8;
// Provides utility functions to compute resting positions for windows which
// wish to avoid other system windows, for example, the PIP and the Automatic
// Clicks bubble menu.
class ASH_EXPORT CollisionDetectionUtils {
public:
enum class Gravity {
kGravityLeft,
kGravityRight,
kGravityTop,
kGravityBottom,
};
// Ordered list of windows which do collision detection. Higher numbers take
// higher priority, i.e. the higher RelativePriority of two windows will not
// move when the windows are in conflict. In this case, that means the
// Picture in Picture window will move out of the way for the Automatic Clicks
// menu, and both will move out of the way for default system windows. Windows
// with the same relative priority will not affect collision with each other.
// kDefault is used for "everything else", and should not be an input to
// GetRestingPosition or AvoidObstacles.
// TODO(crbug.com/955512): Ensure calculations take place from high to low
// priority to reduce number of collision computations.
enum class RelativePriority {
kPictureInPicture = 0,
kAutomaticClicksMenu = 1,
kDefault = 2,
};
CollisionDetectionUtils() = delete;
~CollisionDetectionUtils() = delete;
// Returns the area that the window can be positioned inside for a given
// display |display|.
static gfx::Rect GetMovementArea(const display::Display& display);
// Returns the position the window should come to rest at. For example,
// this will be at a screen edge, not in the middle of the screen.
// TODO(edcourtney): This should consider drag velocity for fling as well.
static gfx::Rect GetRestingPosition(const display::Display& display,
const gfx::Rect& bounds_in_screen,
RelativePriority priority);
// Mark a window as ignored for collision detection.
static void IgnoreWindowForCollisionDetection(aura::Window* window);
// Allows the windows which use CollisionDetectionUtils to mark their relative
// priority when they come in position conflict.
static void MarkWindowPriorityForCollisionDetection(
aura::Window* window,
RelativePriority priority);
// Moves |bounds| such that it does not intersect with system ui areas, such
// as the unified system tray or the floating keyboard.
static gfx::Rect AvoidObstacles(const display::Display& display,
const gfx::Rect& bounds_in_screen,
RelativePriority priority);
// Returns the result of adjusting |bounds| according to |gravity| inside
// |region|.
static gfx::Rect GetAdjustedBoundsByGravity(const gfx::Rect& bounds,
const gfx::Rect& region,
Gravity gravity);
// Returns the gravity that would make |bounds| fall to the closest edge of
// |region|. If |bounds| is outside of |region| then it will return the
// gravity as if |bounds| had fallen outside of |region|. See the below
// diagram for what the gravity regions look like for a point.
// \ TOP /
// \____/ R
// L |\ /| I
// E | \/ | G
// F | /\ | H
// T |/__\| T
// / \
// /BOTTOM
static Gravity GetGravityToClosestEdge(const gfx::Rect& bounds,
const gfx::Rect& region);
private:
friend class CollisionDetectionUtilsDisplayTest;
friend class CollisionDetectionUtilsLogicTest;
// Internal method for collision resolution. Returns a gfx::Rect with the
// same size as |bounds|. That rectangle will not intersect any of the
// rectangles in |rects| and will be completely inside |work_area|. If such a
// rectangle does not exist, returns |bounds|. Otherwise, it will be the
// closest such rectangle to |bounds|.
static gfx::Rect AvoidObstaclesInternal(const gfx::Rect& work_area,
const std::vector<gfx::Rect>& rects,
const gfx::Rect& bounds_in_screen,
RelativePriority priority);
DISALLOW_COPY_AND_ASSIGN(CollisionDetectionUtils);
};
} // namespace ash
#endif // ASH_WM_COLLISION_DETECTION_COLLISION_DETECTION_UTILS_H_