Commit 7919ff12 authored by Nick Diego Yamane's avatar Nick Diego Yamane Committed by Commit Bot

ozone/wayland: Propagate tab drag status changes to platform window

Wayland Ozone backend uses a platform drag-and-drop session to be able
to support the capabilities required by Chrome's tab dragging.
Particularly, keeping track of the focused window and the current mouse
cursor position while the tab/window is dragged around. Further context
can be found at the design doc [1].

So far, it has been relying only on {Run,End}MoveLoop API to trigger
such DND session. It works, but, as it is called after the (dragged)
windows creation and mapping, it is not possible to take the necessary
actions upon window creation or mapping (e.g: issue some dnd/extension
protocol request to the Wayland compositor), which makes it insufficient
to achieve glitches-free tab/window detaching implementation. Which has
been verified while addressing [2][3], and can be seen at video [4].

To fix it, this patch does:

- Add WaylandExtension platform window extension, with a single method
for now, that makes it possible for the upper layer components to start
the window dragging session explicitly;
- Plumbs up Chrome's Browser{Frame,DWTHLinux} such that it starts a
Wayland drag-and-drop session when the tab drag starts.

[1] https://docs.google.com/document/d/1s6OwTi_WC-pS21WLGQYI39yw2m42ZlVolUXBclljXB4/edit?usp=sharing
[2] https://bugs.chromium.org/p/chromium/issues/detail?id=1099418
[3] https://chromium-review.googlesource.com/c/chromium/src/+/2307653
[4] https://www.youtube.com/watch?v=3sWVyA1OagA

R=sky@chromium.org

Bug: 896640
Test: Covered by ozone_unittests
Change-Id: I5e902caa7b495ae585330bc3e3b431bacb139d1e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2346545
Commit-Queue: Nick Yamane <nickdiego@igalia.com>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarMaksim Sisov (GMT+3) <msisov@igalia.com>
Cr-Commit-Position: refs/heads/master@{#797778}
parent 955c73fb
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "ui/base/ui_base_features.h" #include "ui/base/ui_base_features.h"
#include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/ozone_platform.h"
#include "ui/platform_window/extensions/wayland_extension.h"
#include "ui/platform_window/extensions/x11_extension.h" #include "ui/platform_window/extensions/x11_extension.h"
#if defined(USE_DBUS_MENU) #if defined(USE_DBUS_MENU)
...@@ -78,16 +79,26 @@ bool BrowserDesktopWindowTreeHostLinux::UsesNativeSystemMenu() const { ...@@ -78,16 +79,26 @@ bool BrowserDesktopWindowTreeHostLinux::UsesNativeSystemMenu() const {
return false; return false;
} }
void BrowserDesktopWindowTreeHostLinux::TabDraggingStatusChanged( void BrowserDesktopWindowTreeHostLinux::TabDraggingKindChanged(
bool is_dragging) { TabDragKind tab_drag_kind) {
// If there's no tabs left, the browser window is about to close, so don't // If there's no tabs left, the browser window is about to close, so don't
// call SetOverrideRedirect() to prevent the window from flashing. // call SetOverrideRedirect() to prevent the window from flashing.
if (!browser_view_->tabstrip()->GetModelCount()) if (!browser_view_->tabstrip()->GetModelCount())
return; return;
auto* x11_extension = GetX11Extension(); auto* x11_extension = GetX11Extension();
if (x11_extension && x11_extension->IsWmTiling()) if (x11_extension && x11_extension->IsWmTiling()) {
x11_extension->SetOverrideRedirect(is_dragging); bool was_dragging_window =
browser_frame_->tab_drag_kind() == TabDragKind::kAllTabs;
bool is_dragging_window = tab_drag_kind == TabDragKind::kAllTabs;
if (is_dragging_window != was_dragging_window)
x11_extension->SetOverrideRedirect(is_dragging_window);
}
if (auto* wayland_extension = ui::GetWaylandExtension(*platform_window())) {
if (tab_drag_kind != TabDragKind::kNone)
wayland_extension->StartWindowDraggingSessionIfNeeded();
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
......
...@@ -17,6 +17,7 @@ using DesktopWindowTreeHostLinuxImpl = views::DesktopWindowTreeHostLinux; ...@@ -17,6 +17,7 @@ using DesktopWindowTreeHostLinuxImpl = views::DesktopWindowTreeHostLinux;
class BrowserFrame; class BrowserFrame;
class BrowserView; class BrowserView;
enum class TabDragKind;
namespace views { namespace views {
class DesktopNativeWidgetAura; class DesktopNativeWidgetAura;
...@@ -33,8 +34,8 @@ class BrowserDesktopWindowTreeHostLinux ...@@ -33,8 +34,8 @@ class BrowserDesktopWindowTreeHostLinux
BrowserFrame* browser_frame); BrowserFrame* browser_frame);
~BrowserDesktopWindowTreeHostLinux() override; ~BrowserDesktopWindowTreeHostLinux() override;
// Called when the window starts or stops moving because of a tab drag. // Called when the tab drag status changes for this window.
void TabDraggingStatusChanged(bool is_dragging); void TabDraggingKindChanged(TabDragKind tab_drag_kind);
private: private:
// BrowserDesktopWindowTreeHost: // BrowserDesktopWindowTreeHost:
......
...@@ -272,10 +272,8 @@ void BrowserFrame::SetTabDragKind(TabDragKind tab_drag_kind) { ...@@ -272,10 +272,8 @@ void BrowserFrame::SetTabDragKind(TabDragKind tab_drag_kind) {
if (tab_drag_kind_ == tab_drag_kind) if (tab_drag_kind_ == tab_drag_kind)
return; return;
bool was_dragging_window = tab_drag_kind_ == TabDragKind::kAllTabs; if (native_browser_frame_)
bool is_dragging_window = tab_drag_kind == TabDragKind::kAllTabs; native_browser_frame_->TabDraggingKindChanged(tab_drag_kind);
if (was_dragging_window != is_dragging_window && native_browser_frame_)
native_browser_frame_->TabDraggingStatusChanged(is_dragging_window);
bool was_dragging_any = tab_drag_kind_ != TabDragKind::kNone; bool was_dragging_any = tab_drag_kind_ != TabDragKind::kNone;
bool is_dragging_any = tab_drag_kind != TabDragKind::kNone; bool is_dragging_any = tab_drag_kind != TabDragKind::kNone;
......
...@@ -68,8 +68,9 @@ bool DesktopBrowserFrameAuraLinux::UseCustomFrame() const { ...@@ -68,8 +68,9 @@ bool DesktopBrowserFrameAuraLinux::UseCustomFrame() const {
return false; return false;
} }
void DesktopBrowserFrameAuraLinux::TabDraggingStatusChanged(bool is_dragging) { void DesktopBrowserFrameAuraLinux::TabDraggingKindChanged(
host_->TabDraggingStatusChanged(is_dragging); TabDragKind tab_drag_kind) {
host_->TabDraggingKindChanged(tab_drag_kind);
} }
void DesktopBrowserFrameAuraLinux::OnUseCustomChromeFrameChanged() { void DesktopBrowserFrameAuraLinux::OnUseCustomChromeFrameChanged() {
......
...@@ -25,7 +25,7 @@ class DesktopBrowserFrameAuraLinux : public DesktopBrowserFrameAura { ...@@ -25,7 +25,7 @@ class DesktopBrowserFrameAuraLinux : public DesktopBrowserFrameAura {
// Overridden from NativeBrowserFrame: // Overridden from NativeBrowserFrame:
views::Widget::InitParams GetWidgetParams() override; views::Widget::InitParams GetWidgetParams() override;
bool UseCustomFrame() const override; bool UseCustomFrame() const override;
void TabDraggingStatusChanged(bool is_dragging) override; void TabDraggingKindChanged(TabDragKind tab_drag_kind) override;
private: private:
// Called when the preference changes. // Called when the preference changes.
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
class BrowserFrame; class BrowserFrame;
enum class TabDragKind;
namespace content { namespace content {
struct NativeWebKeyboardEvent; struct NativeWebKeyboardEvent;
...@@ -49,8 +50,8 @@ class NativeBrowserFrame { ...@@ -49,8 +50,8 @@ class NativeBrowserFrame {
virtual bool HandleKeyboardEvent( virtual bool HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) = 0; const content::NativeWebKeyboardEvent& event) = 0;
// Called when the window starts or stops moving because of a tab drag. // Called when the tab drag kind for this frame changes.
virtual void TabDraggingStatusChanged(bool is_dragging) {} virtual void TabDraggingKindChanged(TabDragKind tab_drag_kind) {}
protected: protected:
friend class BrowserFrame; friend class BrowserFrame;
......
...@@ -177,6 +177,7 @@ source_set("wayland") { ...@@ -177,6 +177,7 @@ source_set("wayland") {
"//ui/ozone/common", "//ui/ozone/common",
"//ui/ozone/public/mojom/wayland:wayland_mojom", "//ui/ozone/public/mojom/wayland:wayland_mojom",
"//ui/platform_window", "//ui/platform_window",
"//ui/platform_window/extensions",
"//ui/platform_window/wm", "//ui/platform_window/wm",
] ]
...@@ -352,6 +353,7 @@ source_set("wayland_unittests") { ...@@ -352,6 +353,7 @@ source_set("wayland_unittests") {
"//ui/gfx/linux:test_support", "//ui/gfx/linux:test_support",
"//ui/ozone:platform", "//ui/ozone:platform",
"//ui/ozone:test_support", "//ui/ozone:test_support",
"//ui/platform_window/extensions",
"//ui/platform_window/wm", "//ui/platform_window/wm",
] ]
......
...@@ -17,7 +17,9 @@ ...@@ -17,7 +17,9 @@
#include "ui/ozone/platform/wayland/host/wayland_connection.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_data_drag_controller.h" #include "ui/ozone/platform/wayland/host/wayland_data_drag_controller.h"
#include "ui/ozone/platform/wayland/host/wayland_event_source.h" #include "ui/ozone/platform/wayland/host/wayland_event_source.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/ozone/platform/wayland/host/wayland_window_drag_controller.h" #include "ui/ozone/platform/wayland/host/wayland_window_drag_controller.h"
#include "ui/platform_window/extensions/wayland_extension.h"
#include "ui/platform_window/wm/wm_drop_handler.h" #include "ui/platform_window/wm/wm_drop_handler.h"
namespace ui { namespace ui {
...@@ -338,6 +340,7 @@ bool WaylandToplevelWindow::OnInitialize( ...@@ -338,6 +340,7 @@ bool WaylandToplevelWindow::OnInitialize(
#else #else
wm_class_class_ = properties.wm_class_class; wm_class_class_ = properties.wm_class_class;
#endif #endif
SetWaylandExtension(this, static_cast<WaylandExtension*>(this));
SetWmMoveLoopHandler(this, static_cast<WmMoveLoopHandler*>(this)); SetWmMoveLoopHandler(this, static_cast<WmMoveLoopHandler*>(this));
return true; return true;
} }
...@@ -352,6 +355,11 @@ void WaylandToplevelWindow::EndMoveLoop() { ...@@ -352,6 +355,11 @@ void WaylandToplevelWindow::EndMoveLoop() {
connection()->window_drag_controller()->StopDragging(); connection()->window_drag_controller()->StopDragging();
} }
void WaylandToplevelWindow::StartWindowDraggingSessionIfNeeded() {
DCHECK(connection()->window_drag_controller());
connection()->window_drag_controller()->StartDragSession();
}
void WaylandToplevelWindow::TriggerStateChanges() { void WaylandToplevelWindow::TriggerStateChanges() {
if (!shell_surface_) if (!shell_surface_)
return; return;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "build/lacros_buildflags.h" #include "build/lacros_buildflags.h"
#include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/geometry/vector2d.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h" #include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/platform_window/extensions/wayland_extension.h"
#include "ui/platform_window/wm/wm_drag_handler.h" #include "ui/platform_window/wm/wm_drag_handler.h"
#include "ui/platform_window/wm/wm_move_loop_handler.h" #include "ui/platform_window/wm/wm_move_loop_handler.h"
#include "ui/platform_window/wm/wm_move_resize_handler.h" #include "ui/platform_window/wm/wm_move_resize_handler.h"
...@@ -19,7 +20,8 @@ class ShellSurfaceWrapper; ...@@ -19,7 +20,8 @@ class ShellSurfaceWrapper;
class WaylandToplevelWindow : public WaylandWindow, class WaylandToplevelWindow : public WaylandWindow,
public WmMoveResizeHandler, public WmMoveResizeHandler,
public WmDragHandler, public WmDragHandler,
public WmMoveLoopHandler { public WmMoveLoopHandler,
public WaylandExtension {
public: public:
WaylandToplevelWindow(PlatformWindowDelegate* delegate, WaylandToplevelWindow(PlatformWindowDelegate* delegate,
WaylandConnection* connection); WaylandConnection* connection);
...@@ -79,6 +81,9 @@ class WaylandToplevelWindow : public WaylandWindow, ...@@ -79,6 +81,9 @@ class WaylandToplevelWindow : public WaylandWindow,
bool RunMoveLoop(const gfx::Vector2d& drag_offset) override; bool RunMoveLoop(const gfx::Vector2d& drag_offset) override;
void EndMoveLoop() override; void EndMoveLoop() override;
// WaylandExtension:
void StartWindowDraggingSessionIfNeeded() override;
void TriggerStateChanges(); void TriggerStateChanges();
void SetWindowState(PlatformWindowState state); void SetWindowState(PlatformWindowState state);
......
...@@ -64,19 +64,48 @@ WaylandWindowDragController::WaylandWindowDragController( ...@@ -64,19 +64,48 @@ WaylandWindowDragController::WaylandWindowDragController(
WaylandWindowDragController::~WaylandWindowDragController() = default; WaylandWindowDragController::~WaylandWindowDragController() = default;
bool WaylandWindowDragController::Drag(WaylandToplevelWindow* window, bool WaylandWindowDragController::StartDragSession() {
const gfx::Vector2d& offset) { if (state_ != State::kIdle)
DCHECK_LE(state_, State::kAttached); return true;
DCHECK(window);
if (!OfferWindow()) origin_window_ = window_manager_->GetCurrentFocusedWindow();
if (!origin_window_) {
LOG(ERROR) << "Failed to get origin window.";
return false; return false;
}
VLOG(1) << "Starting DND session.";
state_ = State::kAttached;
DCHECK(!data_source_);
data_source_ = data_device_manager_->CreateSource(this);
data_source_->Offer({kMimeTypeChromiumWindow});
data_source_->SetAction(DragDropTypes::DRAG_MOVE);
// TODO(crbug.com/1099418): Use dragged window's surface as icon surface
// once "immediate drag" protocol extensions are available.
data_device_->StartDrag(*data_source_, *origin_window_,
/*icon_surface=*/nullptr, this);
pointer_grab_owner_ = origin_window_;
// Observe window so we can take ownership of the origin surface in case it
// is destroyed during the DND session.
window_manager_->AddObserver(this);
return true;
}
bool WaylandWindowDragController::Drag(WaylandToplevelWindow* window,
const gfx::Vector2d& offset) {
DCHECK_EQ(state_, State::kAttached); DCHECK_EQ(state_, State::kAttached);
DCHECK(window);
dragged_window_ = window; dragged_window_ = window;
drag_offset_ = offset; drag_offset_ = offset;
RunLoop(); RunLoop();
dragged_window_ = nullptr;
DCHECK(state_ == State::kAttached || state_ == State::kDropped); DCHECK(state_ == State::kAttached || state_ == State::kDropped);
bool dropped = state_ == State::kDropped; bool dropped = state_ == State::kDropped;
if (dropped) if (dropped)
...@@ -248,38 +277,6 @@ void WaylandWindowDragController::OnWindowRemoved(WaylandWindow* window) { ...@@ -248,38 +277,6 @@ void WaylandWindowDragController::OnWindowRemoved(WaylandWindow* window) {
origin_surface_ = origin_window_->TakeWaylandSurface(); origin_surface_ = origin_window_->TakeWaylandSurface();
} }
bool WaylandWindowDragController::OfferWindow() {
DCHECK_LE(state_, State::kAttached);
origin_window_ = window_manager_->GetCurrentFocusedWindow();
if (!origin_window_) {
LOG(ERROR) << "Failed to get origin window.";
return false;
}
if (!data_source_)
data_source_ = data_device_manager_->CreateSource(this);
if (state_ == State::kIdle) {
// Observe window so we can take ownership of the origin surface in case it
// is destroyed during the DND session.
window_manager_->AddObserver(this);
VLOG(1) << "Starting DND session.";
state_ = State::kAttached;
data_source_->Offer({kMimeTypeChromiumWindow});
data_source_->SetAction(DragDropTypes::DRAG_MOVE);
// TODO(crbug.com/1099418): Use dragged window's surface as icon surface
// once "immediate drag" protocol extensions are available.
data_device_->StartDrag(*data_source_, *origin_window_,
/*icon_surface=*/nullptr, this);
}
pointer_grab_owner_ = origin_window_;
return true;
}
void WaylandWindowDragController::HandleMotionEvent(MouseEvent* event) { void WaylandWindowDragController::HandleMotionEvent(MouseEvent* event) {
DCHECK_EQ(state_, State::kDetached); DCHECK_EQ(state_, State::kDetached);
DCHECK(dragged_window_); DCHECK(dragged_window_);
...@@ -324,7 +321,8 @@ void WaylandWindowDragController::RunLoop() { ...@@ -324,7 +321,8 @@ void WaylandWindowDragController::RunLoop() {
DCHECK_EQ(state_, State::kAttached); DCHECK_EQ(state_, State::kAttached);
DCHECK(dragged_window_); DCHECK(dragged_window_);
VLOG(1) << "Starting drag loop. widget=" << dragged_window_->GetWidget(); VLOG(1) << "Starting drag loop. widget=" << dragged_window_->GetWidget()
<< " offset=" << drag_offset_.ToString();
// TODO(crbug.com/896640): Handle cursor // TODO(crbug.com/896640): Handle cursor
auto old_dispatcher = std::move(nested_dispatcher_); auto old_dispatcher = std::move(nested_dispatcher_);
......
...@@ -58,7 +58,12 @@ class WaylandWindowDragController : public WaylandDataDevice::DragDelegate, ...@@ -58,7 +58,12 @@ class WaylandWindowDragController : public WaylandDataDevice::DragDelegate,
delete; delete;
~WaylandWindowDragController() override; ~WaylandWindowDragController() override;
bool Drag(WaylandToplevelWindow* surface, const gfx::Vector2d& offset); // Starts a new Wayland DND session for window dragging, if not done yet. A
// new data source is setup and the focused window is used as the origin
// surface.
bool StartDragSession();
bool Drag(WaylandToplevelWindow* window, const gfx::Vector2d& offset);
void StopDragging(); void StopDragging();
State state() const { return state_; } State state() const { return state_; }
...@@ -87,9 +92,6 @@ class WaylandWindowDragController : public WaylandDataDevice::DragDelegate, ...@@ -87,9 +92,6 @@ class WaylandWindowDragController : public WaylandDataDevice::DragDelegate,
// WaylandWindowObserver: // WaylandWindowObserver:
void OnWindowRemoved(WaylandWindow* window) override; void OnWindowRemoved(WaylandWindow* window) override;
// Offers the focused window as available to be dragged. A new data source is
// setup and the underlying DnD session is started, if not done yet.
bool OfferWindow();
// Handles drag/move mouse |event|, while in |kDetached| mode, forwarding it // Handles drag/move mouse |event|, while in |kDetached| mode, forwarding it
// as a bounds change event to the upper layer handlers. // as a bounds change event to the upper layer handlers.
void HandleMotionEvent(MouseEvent* event); void HandleMotionEvent(MouseEvent* event);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h"
#include "ui/ozone/platform/wayland/test/wayland_test.h" #include "ui/ozone/platform/wayland/test/wayland_test.h"
#include "ui/ozone/test/mock_platform_window_delegate.h" #include "ui/ozone/test/mock_platform_window_delegate.h"
#include "ui/platform_window/extensions/wayland_extension.h"
#include "ui/platform_window/platform_window_delegate.h" #include "ui/platform_window/platform_window_delegate.h"
#include "ui/platform_window/wm/wm_move_loop_handler.h" #include "ui/platform_window/wm/wm_move_loop_handler.h"
...@@ -209,10 +210,14 @@ TEST_P(WaylandWindowDragControllerTest, DragInsideWindowAndDrop) { ...@@ -209,10 +210,14 @@ TEST_P(WaylandWindowDragControllerTest, DragInsideWindowAndDrop) {
SendPointerPress(window_.get(), &delegate_, BTN_LEFT); SendPointerPress(window_.get(), &delegate_, BTN_LEFT);
SendPointerMotion(window_.get(), &delegate_, {10, 10}); SendPointerMotion(window_.get(), &delegate_, {10, 10});
// Set up an "interaction flow" and RunMoveLoop: // Set up an "interaction flow", start the drag session and run move loop:
// - Event dispatching and bounds changes are monitored // - Event dispatching and bounds changes are monitored
// - At each event, emulates a new event at server side and proceeds to the // - At each event, emulates a new event at server side and proceeds to the
// next test step. // next test step.
auto* wayland_extension = GetWaylandExtension(*window_);
wayland_extension->StartWindowDraggingSessionIfNeeded();
EXPECT_EQ(State::kAttached, drag_controller()->state());
auto* move_loop_handler = GetWmMoveLoopHandler(*window_); auto* move_loop_handler = GetWmMoveLoopHandler(*window_);
DCHECK(move_loop_handler); DCHECK(move_loop_handler);
...@@ -296,10 +301,14 @@ TEST_P(WaylandWindowDragControllerTest, DragExitWindowAndDrop) { ...@@ -296,10 +301,14 @@ TEST_P(WaylandWindowDragControllerTest, DragExitWindowAndDrop) {
SendPointerPress(window_.get(), &delegate_, BTN_LEFT); SendPointerPress(window_.get(), &delegate_, BTN_LEFT);
SendPointerMotion(window_.get(), &delegate_, {10, 10}); SendPointerMotion(window_.get(), &delegate_, {10, 10});
// Sets up an "interaction flow" and RunMoveLoop: // Sets up an "interaction flow", start the drag session and run move loop:
// - Event dispatching and bounds changes are monitored // - Event dispatching and bounds changes are monitored
// - At each event, emulates a new event on server side and proceeds to the // - At each event, emulates a new event on server side and proceeds to the
// next test step. // next test step.
auto* wayland_extension = GetWaylandExtension(*window_);
wayland_extension->StartWindowDraggingSessionIfNeeded();
EXPECT_EQ(State::kAttached, drag_controller()->state());
auto* move_loop_handler = GetWmMoveLoopHandler(*window_); auto* move_loop_handler = GetWmMoveLoopHandler(*window_);
DCHECK(move_loop_handler); DCHECK(move_loop_handler);
...@@ -408,10 +417,14 @@ TEST_P(WaylandWindowDragControllerTest, DragToOtherWindowSnapDragDrop) { ...@@ -408,10 +417,14 @@ TEST_P(WaylandWindowDragControllerTest, DragToOtherWindowSnapDragDrop) {
SendPointerPress(source_window, &delegate_, BTN_LEFT); SendPointerPress(source_window, &delegate_, BTN_LEFT);
SendPointerMotion(source_window, &delegate_, {10, 10}); SendPointerMotion(source_window, &delegate_, {10, 10});
// Sets up an "interaction flow" and RunMoveLoop: // Sets up an "interaction flow", start the drag session and run move loop:
// - Event dispatching and bounds changes are monitored // - Event dispatching and bounds changes are monitored
// - At each event, emulates a new event on server side and proceeds to the // - At each event, emulates a new event on server side and proceeds to the
// next test step. // next test step.
auto* wayland_extension = GetWaylandExtension(*window_);
wayland_extension->StartWindowDraggingSessionIfNeeded();
EXPECT_EQ(State::kAttached, drag_controller()->state());
auto* move_loop_handler = GetWmMoveLoopHandler(*window_); auto* move_loop_handler = GetWmMoveLoopHandler(*window_);
DCHECK(move_loop_handler); DCHECK(move_loop_handler);
......
...@@ -21,6 +21,8 @@ source_set("extensions") { ...@@ -21,6 +21,8 @@ source_set("extensions") {
if (is_linux || is_chromeos) { if (is_linux || is_chromeos) {
sources += [ sources += [
"wayland_extension.cc",
"wayland_extension.h",
"x11_extension.cc", "x11_extension.cc",
"x11_extension.h", "x11_extension.h",
"x11_extension_delegate.h", "x11_extension_delegate.h",
......
// Copyright 2020 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 "ui/platform_window/extensions/wayland_extension.h"
#include "ui/base/class_property.h"
#include "ui/platform_window/platform_window.h"
DEFINE_UI_CLASS_PROPERTY_TYPE(ui::WaylandExtension*)
namespace ui {
DEFINE_UI_CLASS_PROPERTY_KEY(WaylandExtension*, kWaylandExtensionKey, nullptr)
WaylandExtension::~WaylandExtension() = default;
void WaylandExtension::SetWaylandExtension(PlatformWindow* window,
WaylandExtension* extension) {
window->SetProperty(kWaylandExtensionKey, extension);
}
WaylandExtension* GetWaylandExtension(const PlatformWindow& window) {
return window.GetProperty(kWaylandExtensionKey);
}
} // namespace ui
// Copyright 2020 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 UI_PLATFORM_WINDOW_EXTENSIONS_WAYLAND_EXTENSION_H_
#define UI_PLATFORM_WINDOW_EXTENSIONS_WAYLAND_EXTENSION_H_
#include "base/component_export.h"
namespace ui {
class PlatformWindow;
class COMPONENT_EXPORT(EXTENSIONS) WaylandExtension {
public:
// Starts a window dragging session for the owning platform window, if
// it is not running yet. Under Wayland, window dragging is backed by a
// platform drag-and-drop session.
virtual void StartWindowDraggingSessionIfNeeded() = 0;
protected:
virtual ~WaylandExtension();
// Sets the pointer to the extension as a property of the PlatformWindow.
void SetWaylandExtension(PlatformWindow* window, WaylandExtension* extension);
};
COMPONENT_EXPORT(EXTENSIONS)
WaylandExtension* GetWaylandExtension(const PlatformWindow& window);
} // namespace ui
#endif // UI_PLATFORM_WINDOW_EXTENSIONS_WAYLAND_EXTENSION_H_
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