Commit 4f5be309 authored by Maksim Sisov's avatar Maksim Sisov Committed by Commit Bot

[ozone/wayland] Use touch focused parent if parent is not specified

When context menus are created (with right-click or long touch
press), WaylandWindow must take a focused window as a parent for
that context aka popup window. It has always been so for mouse clicks, but
not for touches.

Now, GetCurrentFocusedWindow returns either a window with
pointer focus or touch focus.

Also fix unittests and their expectations

Bug: 973015
Change-Id: I3c268f3956d57fd673c5e7a8646a30fdd4c921a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1715078
Commit-Queue: Maksim Sisov <msisov@igalia.com>
Reviewed-by: default avatarAntonio Gomes <tonikitoo@igalia.com>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Cr-Commit-Position: refs/heads/master@{#681708}
parent 33b2b1f3
......@@ -70,6 +70,9 @@ class WaylandConnection : public PlatformEventSource,
// Returns the current pointer, which may be null.
WaylandPointer* pointer() const { return pointer_.get(); }
// Returns the current touch, which may be null.
WaylandTouch* touch() const { return touch_.get(); }
WaylandClipboard* clipboard() const { return clipboard_.get(); }
WaylandDataSource* drag_data_source() const {
......
......@@ -105,7 +105,8 @@ WaylandWindow::~WaylandWindow() {
}
PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
connection_->wayland_window_manager()->RemoveWindow(GetWidget());
if (surface_)
connection_->wayland_window_manager()->RemoveWindow(GetWidget());
if (parent_window_)
parent_window_->set_child_window(nullptr);
......@@ -138,6 +139,8 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
wl_surface_set_user_data(surface_.get(), this);
AddSurfaceListener();
connection_->wayland_window_manager()->AddWindow(GetWidget(), this);
ui::PlatformWindowType ui_window_type = properties.type;
switch (ui_window_type) {
case ui::PlatformWindowType::kMenu:
......@@ -145,7 +148,11 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
parent_window_ = GetParentWindow(properties.parent_widget);
// Popups need to know their scale earlier to position themselves.
DCHECK(parent_window_);
if (!parent_window_) {
LOG(ERROR) << "Failed to get a parent window for this popup";
return false;
}
SetBufferScale(parent_window_->buffer_scale_, false);
ui_scale_ = parent_window_->ui_scale_;
......@@ -165,7 +172,6 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
connection_->ScheduleFlush();
connection_->wayland_window_manager()->AddWindow(GetWidget(), this);
PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
delegate_->OnAcceleratedWidgetAvailable(GetWidget());
......
......@@ -78,11 +78,12 @@ class WaylandWindow : public PlatformWindow,
// Set whether this window has keyboard focus and should dispatch key events.
void set_keyboard_focus(bool focus) { has_keyboard_focus_ = focus; }
bool has_keyboard_focus() const { return has_keyboard_focus_; }
// Set whether this window has touch focus and should dispatch touch events.
// The methods set or return whether this window has touch focus and should
// dispatch touch events.
void set_touch_focus(bool focus) { has_touch_focus_ = focus; }
bool has_touch_focus() const { return has_touch_focus_; }
// Set a child of this window. It is very important in case of nested
// xdg_popups as long as they must be destroyed in the back order.
......
......@@ -43,7 +43,7 @@ WaylandWindow* WaylandWindowManager::GetWindowWithLargestBounds() const {
WaylandWindow* WaylandWindowManager::GetCurrentFocusedWindow() const {
for (auto entry : window_map_) {
WaylandWindow* window = entry.second;
if (window->has_pointer_focus())
if (window->has_pointer_focus() || window->has_touch_focus())
return window;
}
return nullptr;
......
......@@ -33,7 +33,7 @@ class WaylandWindowManager {
// Returns a window with largests bounds.
WaylandWindow* GetWindowWithLargestBounds() const;
// Returns a current focused window by pointer.
// Returns a current focused window by pointer or touch.
WaylandWindow* GetCurrentFocusedWindow() const;
// Returns a current focused window by keyboard.
......
......@@ -149,22 +149,20 @@ class WaylandWindowTest : public WaylandTest {
return result;
}
std::unique_ptr<WaylandWindow> CreateWaylandWindowWithParams(
PlatformWindowType type,
gfx::AcceleratedWidget parent_widget,
const gfx::Rect bounds,
MockPlatformWindowDelegate* delegate) {
bool CreateWaylandWindowWithParams(PlatformWindowType type,
gfx::AcceleratedWidget parent_widget,
const gfx::Rect bounds,
MockPlatformWindowDelegate* delegate,
std::unique_ptr<WaylandWindow>* window) {
PlatformWindowInitProperties properties;
// TODO(msisov): use a fancy method to calculate position of a popup window.
properties.bounds = bounds;
properties.type = type;
properties.parent_widget = parent_widget;
std::unique_ptr<WaylandWindow> window =
std::make_unique<WaylandWindow>(delegate, connection_.get());
*window = std::make_unique<WaylandWindow>(delegate, connection_.get());
EXPECT_TRUE(window->Initialize(std::move(properties)));
return window;
return (*window)->Initialize(std::move(properties));
}
void InitializeWithSupportedHitTestValues(std::vector<int>* hit_tests) {
......@@ -728,29 +726,38 @@ TEST_P(WaylandWindowTest, OnAcceleratedWidgetDestroy) {
window_.reset();
}
TEST_P(WaylandWindowTest, CreateAndDestroyMenuWindow) {
TEST_P(WaylandWindowTest, CanCreateMenuWindow) {
MockPlatformWindowDelegate menu_window_delegate;
std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10),
&menu_window_delegate);
// set_pointer_focus(true) requires a WaylandPointer.
wl_seat_send_capabilities(
server_.seat()->resource(),
WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH);
Sync();
ASSERT_TRUE(connection_->pointer() && connection_->touch());
window_->set_pointer_focus(true);
std::unique_ptr<WaylandWindow> menu_window;
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget,
gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window));
Sync();
}
TEST_P(WaylandWindowTest, CreateAndDestroyMenuWindowWithFocusedParent) {
MockPlatformWindowDelegate menu_window_delegate;
window_->set_pointer_focus(false);
window_->set_touch_focus(false);
EXPECT_FALSE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget,
gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window));
// set_pointer_focus(true) requires a WaylandPointer.
wl_seat_send_capabilities(server_.seat()->resource(),
WL_SEAT_CAPABILITY_POINTER);
Sync();
ASSERT_TRUE(connection_->pointer());
window_->set_pointer_focus(true);
std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
window_->set_touch_focus(true);
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget,
gfx::Rect(0, 0, 10, 10), &menu_window_delegate);
gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window));
Sync();
}
......@@ -761,27 +768,29 @@ TEST_P(WaylandWindowTest, CreateAndDestroyNestedMenuWindow) {
EXPECT_CALL(menu_window_delegate, OnAcceleratedWidgetAvailable(_))
.WillOnce(SaveArg<0>(&menu_window_widget));
std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
std::unique_ptr<WaylandWindow> menu_window;
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10),
&menu_window_delegate);
&menu_window_delegate, &menu_window));
ASSERT_NE(menu_window_widget, gfx::kNullAcceleratedWidget);
Sync();
MockPlatformWindowDelegate nested_menu_window_delegate;
std::unique_ptr<WaylandWindow> nested_menu_window =
CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget,
gfx::Rect(20, 0, 10, 10), &nested_menu_window_delegate);
std::unique_ptr<WaylandWindow> nested_menu_window;
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, gfx::Rect(20, 0, 10, 10),
&nested_menu_window_delegate, &nested_menu_window));
Sync();
}
TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNonNested) {
MockPlatformWindowDelegate menu_window_delegate;
std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
std::unique_ptr<WaylandWindow> menu_window;
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10),
&menu_window_delegate);
&menu_window_delegate, &menu_window));
wl_seat_send_capabilities(server_.seat()->resource(),
WL_SEAT_CAPABILITY_POINTER);
......@@ -804,17 +813,18 @@ TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNested) {
EXPECT_CALL(menu_window_delegate, OnAcceleratedWidgetAvailable(_))
.WillOnce(SaveArg<0>(&menu_window_widget));
std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
std::unique_ptr<WaylandWindow> menu_window;
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10),
&menu_window_delegate);
&menu_window_delegate, &menu_window));
Sync();
MockPlatformWindowDelegate nested_menu_window_delegate;
std::unique_ptr<WaylandWindow> nested_menu_window =
CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget,
gfx::Rect(20, 0, 10, 10), &nested_menu_window_delegate);
std::unique_ptr<WaylandWindow> nested_menu_window;
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, gfx::Rect(20, 0, 10, 10),
&nested_menu_window_delegate, &nested_menu_window));
Sync();
......@@ -883,9 +893,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
MockPlatformWindowDelegate menu_window_delegate;
gfx::Rect menu_window_bounds(gfx::Point(440, 76),
menu_window_positioner.size);
std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
std::unique_ptr<WaylandWindow> menu_window;
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, toplevel_window->GetWidget(),
menu_window_bounds, &menu_window_delegate);
menu_window_bounds, &menu_window_delegate, &menu_window));
Sync();
......@@ -903,10 +914,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
MockPlatformWindowDelegate nested_menu_window_delegate;
gfx::Rect nested_menu_window_bounds(gfx::Point(723, 156),
nested_menu_window_positioner.size);
std::unique_ptr<WaylandWindow> nested_menu_window =
CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget,
nested_menu_window_bounds, &nested_menu_window_delegate);
std::unique_ptr<WaylandWindow> nested_menu_window;
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds,
&nested_menu_window_delegate, &nested_menu_window));
Sync();
......@@ -964,9 +975,9 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
// side. Thus, we have to check that anchor rect is correct.
nested_menu_window.reset();
nested_menu_window_bounds.set_origin({723, 258});
nested_menu_window = CreateWaylandWindowWithParams(
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds,
&nested_menu_window_delegate);
&nested_menu_window_delegate, &nested_menu_window));
Sync();
......@@ -1029,9 +1040,9 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
window_->SetBounds(gfx::Rect(0, 0, 2493, 1413));
menu_window_bounds.set_origin({2206, 67});
menu_window = CreateWaylandWindowWithParams(
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, toplevel_window->GetWidget(),
menu_window_bounds, &menu_window_delegate);
menu_window_bounds, &menu_window_delegate, &menu_window));
Sync();
......@@ -1045,9 +1056,9 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
Sync();
nested_menu_window_bounds.set_origin({1905, 147});
nested_menu_window = CreateWaylandWindowWithParams(
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds,
&nested_menu_window_delegate);
&nested_menu_window_delegate, &nested_menu_window));
Sync();
......@@ -1075,9 +1086,9 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
nested_menu_window.reset();
nested_menu_window = CreateWaylandWindowWithParams(
EXPECT_TRUE(CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds,
&nested_menu_window_delegate);
&nested_menu_window_delegate, &nested_menu_window));
Sync();
......
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