Commit b2c41cd3 authored by Jun Mukai's avatar Jun Mukai Committed by Commit Bot

Do not send input events if the event is located at the caption

Currently, if no window is found for a located event for a
captured window, it simply falls back to the main surface. This
means that click events on the frame (title bar) will be sent
to the underlying system through wayland, but that's unnecessary
at all.

This CL checks the located event's location through hit-test
component.

Bug: b/149517682
Test: exo_unittests
Change-Id: I2c314fca3aadea9f81475e7223166b0087b1e0ed
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2062582
Commit-Queue: Jun Mukai <mukai@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#742927}
parent 133db47c
......@@ -881,4 +881,81 @@ TEST_F(ShellSurfaceTest, Popup) {
}
}
TEST_F(ShellSurfaceTest, Caption) {
gfx::Size buffer_size(256, 256);
auto buffer = std::make_unique<Buffer>(
exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
auto surface = std::make_unique<Surface>();
auto shell_surface = std::make_unique<ShellSurface>(surface.get());
surface->Attach(buffer.get());
shell_surface->OnSetFrame(SurfaceFrameType::NORMAL);
surface->Commit();
shell_surface->GetWidget()->SetBounds(gfx::Rect(0, 0, 256, 256));
shell_surface->GetWidget()->GetNativeWindow()->SetCapture();
EXPECT_EQ(WMHelper::GetInstance()->GetCaptureClient()->GetCaptureWindow(),
shell_surface->GetWidget()->GetNativeWindow());
{
// Move the mouse at the caption of the captured window.
ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(5, 5), gfx::Point(5, 5),
ui::EventTimeForNow(), 0, 0);
EXPECT_EQ(nullptr, GetTargetSurfaceForLocatedEvent(&event));
}
{
// Move the mouse at the center of the captured window.
gfx::Rect bounds = shell_surface->GetWidget()->GetWindowBoundsInScreen();
gfx::Point center = bounds.CenterPoint();
ui::MouseEvent event(ui::ET_MOUSE_MOVED, center - bounds.OffsetFromOrigin(),
center, ui::EventTimeForNow(), 0, 0);
EXPECT_EQ(surface.get(), GetTargetSurfaceForLocatedEvent(&event));
}
}
TEST_F(ShellSurfaceTest, CaptionWithPopup) {
gfx::Size buffer_size(256, 256);
auto buffer = std::make_unique<Buffer>(
exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
auto surface = std::make_unique<Surface>();
auto shell_surface = std::make_unique<ShellSurface>(surface.get());
surface->Attach(buffer.get());
surface->Commit();
shell_surface->GetWidget()->SetBounds(gfx::Rect(0, 0, 256, 256));
shell_surface->OnSetFrame(SurfaceFrameType::NORMAL);
auto popup_buffer = std::make_unique<Buffer>(
exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
auto popup_surface = std::make_unique<Surface>();
popup_surface->Attach(popup_buffer.get());
std::unique_ptr<ShellSurface> popup_shell_surface(CreatePopupShellSurface(
popup_surface.get(), shell_surface.get(), gfx::Point(50, 50)));
popup_shell_surface->Grab();
popup_surface->Commit();
EXPECT_EQ(WMHelper::GetInstance()->GetCaptureClient()->GetCaptureWindow(),
popup_shell_surface->GetWidget()->GetNativeWindow());
{
// Move the mouse at the popup window.
ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(5, 5),
gfx::Point(55, 55), ui::EventTimeForNow(), 0, 0);
EXPECT_EQ(popup_surface.get(), GetTargetSurfaceForLocatedEvent(&event));
}
{
// Move the mouse at the caption of the main window.
ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(-45, -45),
gfx::Point(5, 5), ui::EventTimeForNow(), 0, 0);
EXPECT_EQ(nullptr, GetTargetSurfaceForLocatedEvent(&event));
}
{
// Move the mouse in the main window.
ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(-25, 0),
gfx::Point(25, 50), ui::EventTimeForNow(), 0, 0);
EXPECT_EQ(surface.get(), GetTargetSurfaceForLocatedEvent(&event));
}
}
} // namespace exo
......@@ -16,6 +16,7 @@
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/events/event.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h"
......@@ -40,6 +41,22 @@ DEFINE_UI_CLASS_PROPERTY_KEY(int32_t, kClientAccessibilityIdKey, -1)
// Permission object allowing this window to activate itself.
DEFINE_UI_CLASS_PROPERTY_KEY(exo::Permission*, kPermissionKey, nullptr)
// Returns true if the component for a located event should be taken care of
// by the window system.
bool ShouldHTComponentBlocked(int component) {
switch (component) {
case HTCAPTION:
case HTCLOSE:
case HTMAXBUTTON:
case HTMINBUTTON:
case HTMENU:
case HTSYSMENU:
return true;
default:
return false;
}
}
} // namespace
void SetShellApplicationId(aura::Window* window,
......@@ -116,7 +133,7 @@ ShellSurfaceBase* GetShellSurfaceBaseForWindow(aura::Window* window) {
Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) {
aura::Window* window =
WMHelper::GetInstance()->GetCaptureClient()->GetCaptureWindow();
gfx::PointF location_in_target = event->location_f();
gfx::PointF location_in_target_f = event->location_f();
if (!window)
return Surface::AsSurface(static_cast<aura::Window*>(event->target()));
......@@ -133,22 +150,28 @@ Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) {
}
while (true) {
aura::Window* focused = window->GetEventHandlerForPoint(
gfx::ToFlooredPoint(location_in_target));
gfx::Point location_in_target = gfx::ToFlooredPoint(location_in_target_f);
aura::Window* focused = window->GetEventHandlerForPoint(location_in_target);
if (focused) {
aura::Window::ConvertPointToTarget(window, focused, &location_in_target);
if (focused)
return Surface::AsSurface(focused);
// If the event falls into the place where the window system should care
// about (i.e. window caption), do not check the transient parent but just
// return nullptr. See b/149517682.
if (window->delegate() &&
ShouldHTComponentBlocked(
window->delegate()->GetNonClientComponent(location_in_target))) {
return nullptr;
}
aura::Window* parent_window = wm::GetTransientParent(window);
if (!parent_window) {
location_in_target = event->location_f();
if (!parent_window)
return main_surface;
}
aura::Window::ConvertPointToTarget(window, parent_window,
&location_in_target);
&location_in_target_f);
window = parent_window;
}
}
......
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