blob: ff208c0c0546a3399d46069c6e3c3155f9177d93 [file] [log] [blame]
// Copyright 2021 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.
#include "ash/utility/rounded_window_targeter.h"
#include <memory>
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/events/base_event_utils.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
namespace {
constexpr int kRadius = 80;
} // namespace
class RoundedWindowTargeterTest : public aura::test::AuraTestBase {
public:
RoundedWindowTargeterTest() = default;
RoundedWindowTargeterTest(const RoundedWindowTargeterTest&) = delete;
RoundedWindowTargeterTest& operator=(const RoundedWindowTargeterTest&) =
delete;
~RoundedWindowTargeterTest() override = default;
protected:
void SetUp() override {
aura::test::AuraTestBase::SetUp();
window_.reset(CreateNormalWindow(1, root_window(), &delegate_));
}
void TearDown() override {
window_.reset();
aura::test::AuraTestBase::TearDown();
}
std::unique_ptr<aura::Window> window_;
private:
aura::test::TestWindowDelegate delegate_;
};
/*
Window shape (global coordinates)
(0,0)_____________
|. * | * | <- mouse move (1,1)
| * | * |
|*_____| *|
|* (r,r) *|
| * * |
|____*___*____|
(2r, 2r)
This mouse event hits the square but not the circular window targeter.*/
TEST_F(RoundedWindowTargeterTest, HitTestTopLeftCorner) {
constexpr gfx::Point kTopLeftCorner(1, 1);
{
// Without the RoundedWindowTargeter, the event in the top-left corner
// should target the window.
ui::MouseEvent move(ui::ET_MOUSE_MOVED, kTopLeftCorner, kTopLeftCorner,
ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
ui::EventDispatchDetails details = GetEventSink()->OnEventFromSource(&move);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(window_.get(), move.target());
}
window_->SetEventTargeter(
std::make_unique<ash::RoundedWindowTargeter>(kRadius));
{
// With the RoundedWindowTargeter, the event in the top-left corner should
// fall through to the root window.
ui::MouseEvent move(ui::ET_MOUSE_MOVED, kTopLeftCorner, kTopLeftCorner,
ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
ui::EventDispatchDetails details = GetEventSink()->OnEventFromSource(&move);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(root_window(), move.target());
}
}
/*
Window shape (global coordinates)
(0,0)_____________
| * | * |
| * | * |
|*_____| *| <- mouse move (r,r)
|* (r,r) *|
| * * |
|____*___*____|
(2r, 2r)
This mouse event hits both the square and the circular window targeter.*/
TEST_F(RoundedWindowTargeterTest, HitTestCenter) {
constexpr gfx::Point kCenter(kRadius, kRadius);
{
// Without the RoundedWindowTargeter, the event in the center should target
// the window.
ui::MouseEvent move(ui::ET_MOUSE_MOVED, kCenter, kCenter,
ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
ui::EventDispatchDetails details = GetEventSink()->OnEventFromSource(&move);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(window_.get(), move.target());
}
window_->SetEventTargeter(
std::make_unique<ash::RoundedWindowTargeter>(kRadius));
{
// With the RoundedWindowTargeter, the event in the center should still
// target the window.
ui::MouseEvent move(ui::ET_MOUSE_MOVED, kCenter, kCenter,
ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
ui::EventDispatchDetails details = GetEventSink()->OnEventFromSource(&move);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(window_.get(), move.target());
}
}
/*
Window shape (global coordinates)
(0,0)_____________
| * | * |
| * | * |
|*_____| *|
|* (r,r) *|
| * * |
|____*___*____|
(2r, 2r) <- <- mouse move (2r, 2r)
This mouse event misses both the square and the circular window targeter.*/
TEST_F(RoundedWindowTargeterTest, HitTestBottomRightCorner) {
constexpr gfx::Point kBottomRightCorner(2 * kRadius, 2 * kRadius);
{
// Without the RoundedWindowTargeter, the event in the bottom-right corner
// should fall through to the root window.
ui::MouseEvent move(ui::ET_MOUSE_MOVED, kBottomRightCorner,
kBottomRightCorner, ui::EventTimeForNow(), ui::EF_NONE,
ui::EF_NONE);
ui::EventDispatchDetails details = GetEventSink()->OnEventFromSource(&move);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(root_window(), move.target());
}
window_->SetEventTargeter(
std::make_unique<ash::RoundedWindowTargeter>(kRadius));
{
// With the RoundedWindowTargeter, the event in the bottom-right corner
// should also fall through to the root window.
ui::MouseEvent move(ui::ET_MOUSE_MOVED, kBottomRightCorner,
kBottomRightCorner, ui::EventTimeForNow(), ui::EF_NONE,
ui::EF_NONE);
ui::EventDispatchDetails details = GetEventSink()->OnEventFromSource(&move);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(root_window(), move.target());
}
}