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