summaryrefslogtreecommitdiff
path: root/chromium/ui/platform_window
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/ui/platform_window
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/ui/platform_window')
-rw-r--r--chromium/ui/platform_window/BUILD.gn4
-rw-r--r--chromium/ui/platform_window/fuchsia/initialize_presenter_api_view.cc15
-rw-r--r--chromium/ui/platform_window/platform_window_handler/wm_drag_handler.cc2
-rw-r--r--chromium/ui/platform_window/platform_window_handler/wm_drag_handler.h22
-rw-r--r--chromium/ui/platform_window/x11/BUILD.gn35
-rw-r--r--chromium/ui/platform_window/x11/atk_event_conversion.cc12
-rw-r--r--chromium/ui/platform_window/x11/atk_event_conversion.h3
-rw-r--r--chromium/ui/platform_window/x11/x11_topmost_window_finder.cc25
-rw-r--r--chromium/ui/platform_window/x11/x11_topmost_window_finder.h11
-rw-r--r--chromium/ui/platform_window/x11/x11_window.cc224
-rw-r--r--chromium/ui/platform_window/x11/x11_window.h71
11 files changed, 346 insertions, 78 deletions
diff --git a/chromium/ui/platform_window/BUILD.gn b/chromium/ui/platform_window/BUILD.gn
index 4a96342b2ec..f06af0fb93c 100644
--- a/chromium/ui/platform_window/BUILD.gn
+++ b/chromium/ui/platform_window/BUILD.gn
@@ -16,6 +16,8 @@ component("platform_window") {
defines = [ "IS_PLATFORM_WINDOW_IMPL" ]
+ public_deps = [ "//ui/base/cursor:cursor_base" ]
+
deps = [
"//base",
"//ui/base",
@@ -28,7 +30,7 @@ component("platform_window") {
"fuchsia/initialize_presenter_api_view.h",
]
- public_deps = [
+ public_deps += [
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.policy",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.views",
"//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
diff --git a/chromium/ui/platform_window/fuchsia/initialize_presenter_api_view.cc b/chromium/ui/platform_window/fuchsia/initialize_presenter_api_view.cc
index 292c4ae2cca..7500fcb198e 100644
--- a/chromium/ui/platform_window/fuchsia/initialize_presenter_api_view.cc
+++ b/chromium/ui/platform_window/fuchsia/initialize_presenter_api_view.cc
@@ -5,13 +5,14 @@
#include "ui/platform_window/fuchsia/initialize_presenter_api_view.h"
#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
-#include "base/fuchsia/default_context.h"
+#include <utility>
+
#include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/process_context.h"
namespace ui {
namespace fuchsia {
@@ -21,19 +22,19 @@ void InitializeViewTokenAndPresentView(
DCHECK(window_properties_out);
// Generate ViewToken and ViewHolderToken for the new view.
- ::fuchsia::ui::views::ViewHolderToken view_holder_token;
- std::tie(window_properties_out->view_token, view_holder_token) =
- scenic::NewViewTokenPair();
+ auto view_tokens = scenic::ViewTokenPair::New();
+ window_properties_out->view_token = std::move(view_tokens.view_token);
// Create a ViewRefPair so the view can be registered to the SemanticsManager.
window_properties_out->view_ref_pair = scenic::ViewRefPair::New();
// Request Presenter to show the view full-screen.
- auto presenter = base::fuchsia::ComponentContextForCurrentProcess()
+ auto presenter = base::ComponentContextForProcess()
->svc()
->Connect<::fuchsia::ui::policy::Presenter>();
- presenter->PresentView(std::move(view_holder_token), nullptr);
+ presenter->PresentOrReplaceView(std::move(view_tokens.view_holder_token),
+ nullptr);
}
} // namespace fuchsia
diff --git a/chromium/ui/platform_window/platform_window_handler/wm_drag_handler.cc b/chromium/ui/platform_window/platform_window_handler/wm_drag_handler.cc
index f559d426b49..5dafa35363a 100644
--- a/chromium/ui/platform_window/platform_window_handler/wm_drag_handler.cc
+++ b/chromium/ui/platform_window/platform_window_handler/wm_drag_handler.cc
@@ -13,6 +13,8 @@ namespace ui {
DEFINE_UI_CLASS_PROPERTY_KEY(WmDragHandler*, kWmDragHandlerKey, nullptr)
+WmDragHandler::Delegate::~Delegate() = default;
+
void SetWmDragHandler(PlatformWindow* platform_window,
WmDragHandler* drag_handler) {
platform_window->SetProperty(kWmDragHandlerKey, drag_handler);
diff --git a/chromium/ui/platform_window/platform_window_handler/wm_drag_handler.h b/chromium/ui/platform_window/platform_window_handler/wm_drag_handler.h
index 7f7d7933fab..d1f7510e0c2 100644
--- a/chromium/ui/platform_window/platform_window_handler/wm_drag_handler.h
+++ b/chromium/ui/platform_window/platform_window_handler/wm_drag_handler.h
@@ -6,6 +6,8 @@
#define UI_PLATFORM_WINDOW_PLATFORM_WINDOW_HANDLER_WM_DRAG_HANDLER_H_
#include "base/bind.h"
+#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/gfx/geometry/point.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/platform_window/platform_window_handler/wm_platform_export.h"
@@ -15,15 +17,31 @@ class OSExchangeData;
class WM_PLATFORM_EXPORT WmDragHandler {
public:
+ // During the drag operation, the handler may send updates
+ class Delegate {
+ public:
+ // Called every time when the drag location has changed.
+ virtual void OnDragLocationChanged(const gfx::Point& screen_point_px) = 0;
+ // Called when the currently negotiated operation has changed.
+ virtual void OnDragOperationChanged(
+ DragDropTypes::DragOperation operation) = 0;
+ // Called once when the operation has finished.
+ virtual void OnDragFinished(int operation) = 0;
+
+ protected:
+ virtual ~Delegate();
+ };
+
// Starts dragging with |data| which it wants to deliver to the destination.
// |operation| is the suggested operation which is bitmask of DRAG_NONE,
// DRAG_MOVE, DRAG_COPY and DRAG_LINK in DragDropTypes::DragOperation to the
// destination and the destination sets the final operation when the drop
- // action is performed.
+ // action is performed. In progress updates on the drag operation come back
+ // through the |delegate|.
virtual void StartDrag(const OSExchangeData& data,
int operation,
gfx::NativeCursor cursor,
- base::OnceCallback<void(int)> callback) = 0;
+ Delegate* delegate) = 0;
protected:
virtual ~WmDragHandler() {}
diff --git a/chromium/ui/platform_window/x11/BUILD.gn b/chromium/ui/platform_window/x11/BUILD.gn
index 60228f2c548..a9d6bc31204 100644
--- a/chromium/ui/platform_window/x11/BUILD.gn
+++ b/chromium/ui/platform_window/x11/BUILD.gn
@@ -4,6 +4,7 @@
import("//build/config/jumbo.gni")
import("//build/config/ui.gni")
+import("//testing/test.gni")
import("//ui/ozone/ozone.gni")
assert(use_x11 || ozone_platform_x11)
@@ -49,3 +50,37 @@ jumbo_component("x11") {
deps += [ "//ui/events/x" ]
}
}
+
+test("x11_unittests") {
+ sources = [ "test/x11_window_unittest.cc" ]
+ deps = [
+ ":x11",
+ "//base/test:run_all_unittests",
+ "//base/test:test_support",
+ "//skia",
+ "//testing/gmock",
+ "//testing/gtest",
+ "//ui/base/x",
+ "//ui/base/x:test_support",
+ "//ui/events:test_support",
+ "//ui/events/platform/x11",
+ "//ui/events/x",
+ "//ui/gfx:test_support",
+ "//ui/gfx/x",
+ "//ui/platform_window",
+ "//ui/platform_window/extensions",
+ ]
+ configs += [ "//build/config:precompiled_headers" ]
+
+ # Needed for tests. Please note that if you want to run tests locally,
+ # ensure that you start them from your out directory with the xvfb
+ # script so that openbox has time to start. Otherwise, the x11_unittests
+ # will time out. e.g. -
+ #
+ # 1) cd out/Debug.
+ # 2) ../../testing/xvfb.py ./x11_unittests.
+ #
+ #TODO(dpranke): move that to appropriate place after test() template is
+ # reworked.
+ data_deps = [ "//ui/base/x/xwmstartupcheck" ]
+}
diff --git a/chromium/ui/platform_window/x11/atk_event_conversion.cc b/chromium/ui/platform_window/x11/atk_event_conversion.cc
index b79fff06bb0..6b5a82dbfe7 100644
--- a/chromium/ui/platform_window/x11/atk_event_conversion.cc
+++ b/chromium/ui/platform_window/x11/atk_event_conversion.cc
@@ -10,13 +10,15 @@
namespace ui {
-std::unique_ptr<AtkKeyEventStruct> AtkKeyEventFromXEvent(XEvent* xevent) {
- DCHECK(xevent);
+std::unique_ptr<AtkKeyEventStruct> AtkKeyEventFromXEvent(
+ x11::Event* x11_event) {
+ DCHECK(x11_event);
+ XEvent* xevent = &x11_event->xlib_event();
auto atk_key_event = std::make_unique<AtkKeyEventStruct>();
- if (xevent->type == KeyPress)
+ if (xevent->type == x11::KeyEvent::Press)
atk_key_event->type = ATK_KEY_EVENT_PRESS;
- else if (xevent->type == KeyRelease)
+ else if (xevent->type == x11::KeyEvent::Release)
atk_key_event->type = ATK_KEY_EVENT_RELEASE;
else
NOTREACHED() << xevent->type;
@@ -35,7 +37,7 @@ std::unique_ptr<AtkKeyEventStruct> AtkKeyEventFromXEvent(XEvent* xevent) {
atk_key_event->string = nullptr;
atk_key_event->length = 0;
- int flags = ui::EventFlagsFromXEvent(*xevent);
+ int flags = ui::EventFlagsFromXEvent(*x11_event);
if (flags & ui::EF_SHIFT_DOWN)
atk_key_event->state |= AtkKeyModifierMask::kAtkShiftMask;
if (flags & ui::EF_CAPS_LOCK_ON)
diff --git a/chromium/ui/platform_window/x11/atk_event_conversion.h b/chromium/ui/platform_window/x11/atk_event_conversion.h
index 6a2dce7fbe6..ad15f27db48 100644
--- a/chromium/ui/platform_window/x11/atk_event_conversion.h
+++ b/chromium/ui/platform_window/x11/atk_event_conversion.h
@@ -9,6 +9,7 @@
#include <memory>
+#include "ui/gfx/x/event.h"
#include "ui/gfx/x/x11.h"
namespace ui {
@@ -27,7 +28,7 @@ typedef enum {
KAtkMod5Mask = 1 << 7,
} AtkKeyModifierMask;
-std::unique_ptr<AtkKeyEventStruct> AtkKeyEventFromXEvent(XEvent* xev);
+std::unique_ptr<AtkKeyEventStruct> AtkKeyEventFromXEvent(x11::Event* xev);
} // namespace ui
diff --git a/chromium/ui/platform_window/x11/x11_topmost_window_finder.cc b/chromium/ui/platform_window/x11/x11_topmost_window_finder.cc
index 4163e3b9db3..2b8edfc02db 100644
--- a/chromium/ui/platform_window/x11/x11_topmost_window_finder.cc
+++ b/chromium/ui/platform_window/x11/x11_topmost_window_finder.cc
@@ -8,6 +8,7 @@
#include <vector>
+#include "ui/gfx/native_widget_types.h"
#include "ui/platform_window/x11/x11_window.h"
#include "ui/platform_window/x11/x11_window_manager.h"
@@ -17,7 +18,7 @@ X11TopmostWindowFinder::X11TopmostWindowFinder() = default;
X11TopmostWindowFinder::~X11TopmostWindowFinder() = default;
-XID X11TopmostWindowFinder::FindLocalProcessWindowAt(
+x11::Window X11TopmostWindowFinder::FindLocalProcessWindowAt(
const gfx::Point& screen_loc_in_pixels,
const std::set<gfx::AcceleratedWidget>& ignore) {
screen_loc_in_pixels_ = screen_loc_in_pixels;
@@ -28,35 +29,37 @@ XID X11TopmostWindowFinder::FindLocalProcessWindowAt(
if (std::none_of(local_process_windows.cbegin(), local_process_windows.cend(),
[this](auto* window) {
return ShouldStopIteratingAtLocalProcessWindow(window);
- }))
- return gfx::kNullAcceleratedWidget;
+ })) {
+ return x11::Window::None;
+ }
EnumerateTopLevelWindows(this);
return toplevel_;
}
-XID X11TopmostWindowFinder::FindWindowAt(
+x11::Window X11TopmostWindowFinder::FindWindowAt(
const gfx::Point& screen_loc_in_pixels) {
screen_loc_in_pixels_ = screen_loc_in_pixels;
EnumerateTopLevelWindows(this);
return toplevel_;
}
-bool X11TopmostWindowFinder::ShouldStopIterating(XID xid) {
- if (!IsWindowVisible(xid))
+bool X11TopmostWindowFinder::ShouldStopIterating(x11::Window xwindow) {
+ if (!IsWindowVisible(xwindow))
return false;
- auto* window = X11WindowManager::GetInstance()->GetWindow(xid);
+ auto* window = X11WindowManager::GetInstance()->GetWindow(
+ static_cast<gfx::AcceleratedWidget>(xwindow));
if (window) {
if (ShouldStopIteratingAtLocalProcessWindow(window)) {
- toplevel_ = xid;
+ toplevel_ = xwindow;
return true;
}
return false;
}
- if (WindowContainsPoint(xid, screen_loc_in_pixels_)) {
- toplevel_ = xid;
+ if (WindowContainsPoint(xwindow, screen_loc_in_pixels_)) {
+ toplevel_ = xwindow;
return true;
}
return false;
@@ -72,7 +75,7 @@ bool X11TopmostWindowFinder::ShouldStopIteratingAtLocalProcessWindow(
if (!window->IsVisible())
return false;
- gfx::Rect window_bounds = window->GetOutterBounds();
+ gfx::Rect window_bounds = window->GetOuterBounds();
if (!window_bounds.Contains(screen_loc_in_pixels_))
return false;
diff --git a/chromium/ui/platform_window/x11/x11_topmost_window_finder.h b/chromium/ui/platform_window/x11/x11_topmost_window_finder.h
index 62c9e138d72..0ad199f5ccf 100644
--- a/chromium/ui/platform_window/x11/x11_topmost_window_finder.h
+++ b/chromium/ui/platform_window/x11/x11_topmost_window_finder.h
@@ -30,15 +30,16 @@ class X11_WINDOW_EXPORT X11TopmostWindowFinder
// Returns the topmost window at |screen_loc_in_pixels|, ignoring the windows
// in |ignore|. Returns null widget if the topmost window at
// |screen_loc_in_pixels| does not belong to Chrome.
- XID FindLocalProcessWindowAt(const gfx::Point& screen_loc_in_pixels,
- const std::set<gfx::AcceleratedWidget>& ignore);
+ x11::Window FindLocalProcessWindowAt(
+ const gfx::Point& screen_loc_in_pixels,
+ const std::set<gfx::AcceleratedWidget>& ignore);
// Returns the topmost window at |screen_loc_in_pixels|.
- XID FindWindowAt(const gfx::Point& screen_loc_in_pixels) override;
+ x11::Window FindWindowAt(const gfx::Point& screen_loc_in_pixels) override;
private:
// ui::EnumerateWindowsDelegate:
- bool ShouldStopIterating(XID xid) override;
+ bool ShouldStopIterating(x11::Window window) override;
// Returns true if |window| does not not belong to |ignore|, is visible and
// contains |screen_loc_|.
@@ -46,7 +47,7 @@ class X11_WINDOW_EXPORT X11TopmostWindowFinder
gfx::Point screen_loc_in_pixels_;
std::set<gfx::AcceleratedWidget> ignore_;
- XID toplevel_ = x11::None;
+ x11::Window toplevel_ = x11::Window::None;
DISALLOW_COPY_AND_ASSIGN(X11TopmostWindowFinder);
};
diff --git a/chromium/ui/platform_window/x11/x11_window.cc b/chromium/ui/platform_window/x11/x11_window.cc
index c9fc5e2670d..bc2c18233b7 100644
--- a/chromium/ui/platform_window/x11/x11_window.cc
+++ b/chromium/ui/platform_window/x11/x11_window.cc
@@ -7,6 +7,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "ui/base/buildflags.h"
+#include "ui/base/x/x11_cursor.h"
#include "ui/base/x/x11_desktop_window_move_client.h"
#include "ui/base/x/x11_util.h"
#include "ui/base/x/x11_util_internal.h"
@@ -24,7 +25,15 @@
#include "ui/platform_window/x11/x11_window_manager.h"
#if defined(USE_OZONE)
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/x/x11_os_exchange_data_provider.h"
+#include "ui/base/x/x11_pointer_grab.h"
+#include "ui/base/x/x11_topmost_window_finder.h"
#include "ui/events/ozone/events_ozone.h"
+#include "ui/platform_window/platform_window_handler/wm_drop_handler.h"
+#include "ui/platform_window/x11/x11_topmost_window_finder.h"
+#else
+#include "ui/base/dragdrop/os_exchange_data_provider_x11.h"
#endif // defined(USE_OZONE)
#if BUILDFLAG(USE_ATK)
@@ -35,6 +44,9 @@ namespace ui {
namespace {
+// Opacity for drag widget windows.
+constexpr float kDragWidgetOpacity = .75f;
+
XWindow::WindowOpacity GetXWindowOpacity(PlatformWindowOpacity opacity) {
using WindowOpacity = XWindow::WindowOpacity;
switch (opacity) {
@@ -91,12 +103,15 @@ ui::XWindow::Configuration ConvertInitPropertiesToXWindowConfig(
}
// Coalesce touch/mouse events if needed
-bool CoalesceEventsIfNeeded(XEvent* const xev, EventType type, XEvent* out) {
- if (xev->type == MotionNotify ||
- (xev->type == GenericEvent &&
+bool CoalesceEventsIfNeeded(x11::Event* const x11_event,
+ EventType type,
+ x11::Event* out) {
+ XEvent* xev = &x11_event->xlib_event();
+ if (xev->type == x11::MotionNotifyEvent::opcode ||
+ (xev->type == x11::GeGenericEvent::opcode &&
(type == ui::ET_TOUCH_MOVED || type == ui::ET_MOUSE_MOVED ||
type == ui::ET_MOUSE_DRAGGED))) {
- return ui::CoalescePendingMotionEvents(xev, out) > 0;
+ return ui::CoalescePendingMotionEvents(x11_event, out) > 0;
}
return false;
}
@@ -130,11 +145,27 @@ void X11Window::Initialize(PlatformWindowInitProperties properties) {
config.override_redirect =
properties.x11_extension_delegate &&
properties.x11_extension_delegate->IsOverrideRedirect(IsWmTiling());
+ if (config.type == WindowType::kDrag) {
+ config.opacity = ui::IsCompositingManagerPresent()
+ ? WindowOpacity::kTranslucentWindow
+ : WindowOpacity::kOpaqueWindow;
+ }
workspace_extension_delegate_ = properties.workspace_extension_delegate;
x11_extension_delegate_ = properties.x11_extension_delegate;
Init(config);
+
+ if (config.type == WindowType::kDrag &&
+ config.opacity == WindowOpacity::kTranslucentWindow) {
+ SetOpacity(kDragWidgetOpacity);
+ }
+
+#if defined(USE_OZONE)
+ SetWmDragHandler(this, this);
+
+ drag_drop_client_ = std::make_unique<XDragDropClient>(this, window());
+#endif
}
void X11Window::SetXEventDelegate(XEventDelegate* delegate) {
@@ -359,11 +390,7 @@ bool X11Window::ShouldUseNativeFrame() const {
}
void X11Window::SetCursor(PlatformCursor cursor) {
- // X11PlatformWindowOzone has different type of PlatformCursor. Thus, use this
- // only for X11 and Ozone will manage this by itself.
-#if defined(USE_X11)
- XWindow::SetCursor(cursor);
-#endif
+ XWindow::SetCursor(static_cast<X11Cursor*>(cursor)->xcursor());
}
void X11Window::MoveCursorTo(const gfx::Point& location) {
@@ -409,8 +436,8 @@ ZOrderLevel X11Window::GetZOrderLevel() const {
}
void X11Window::StackAbove(gfx::AcceleratedWidget widget) {
- // Check comment in the GetWidget method about this this cast.
- XWindow::StackXWindowAbove(static_cast<::Window>(widget));
+ // Check comment in the GetWidget method about this cast.
+ XWindow::StackXWindowAbove(static_cast<x11::Window>(widget));
}
void X11Window::StackAtTop() {
@@ -482,7 +509,7 @@ void X11Window::OnCompleteSwapAfterResize() {
}
gfx::Rect X11Window::GetXRootWindowOuterBounds() const {
- return XWindow::GetOutterBounds();
+ return XWindow::GetOuterBounds();
}
bool X11Window::ContainsPointInXRegion(const gfx::Point& point) const {
@@ -501,17 +528,19 @@ void X11Window::SetX11ExtensionDelegate(X11ExtensionDelegate* delegate) {
x11_extension_delegate_ = delegate;
}
-bool X11Window::HandleAsAtkEvent(XEvent* xev) {
+bool X11Window::HandleAsAtkEvent(x11::Event* x11_event) {
#if !BUILDFLAG(USE_ATK)
// TODO(crbug.com/1014934): Support ATK in Ozone/X11.
NOTREACHED();
return false;
#else
+ XEvent* xev = &x11_event->xlib_event();
DCHECK(xev);
- if (!x11_extension_delegate_ ||
- (xev->type != KeyPress && xev->type != KeyRelease))
+ if (!x11_extension_delegate_ || (xev->type != x11::KeyEvent::Press &&
+ xev->type != x11::KeyEvent::Release)) {
return false;
- auto atk_key_event = AtkKeyEventFromXEvent(xev);
+ }
+ auto atk_key_event = AtkKeyEventFromXEvent(x11_event);
return x11_extension_delegate_->OnAtkKeyEvent(atk_key_event.get());
#endif
}
@@ -521,7 +550,7 @@ bool X11Window::HandleAsAtkEvent(XEvent* xev) {
// able to process next translated event sent by it. So, it's done through
// |handle_next_event_| internal flag, used in subsequent CanDispatchEvent
// call.
-void X11Window::CheckCanDispatchNextPlatformEvent(XEvent* xev) {
+void X11Window::CheckCanDispatchNextPlatformEvent(x11::Event* xev) {
if (is_shutting_down_)
return;
current_xevent_ = XWindow::IsTargetedBy(*xev) ? xev : nullptr;
@@ -535,7 +564,7 @@ PlatformEventDispatcher* X11Window::GetPlatformEventDispatcher() {
return this;
}
-bool X11Window::DispatchXEvent(XEvent* xev) {
+bool X11Window::DispatchXEvent(x11::Event* xev) {
if (!XWindow::IsTargetedBy(*xev))
return false;
XWindow::ProcessEvent(xev);
@@ -543,7 +572,7 @@ bool X11Window::DispatchXEvent(XEvent* xev) {
}
bool X11Window::CanDispatchEvent(const PlatformEvent& xev) {
- DCHECK_NE(window(), x11::None);
+ DCHECK_NE(window(), x11::Window::None);
return !!current_xevent_;
}
@@ -551,7 +580,7 @@ uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
TRACE_EVENT1("views", "X11PlatformWindow::Dispatch", "event->type()",
event->type());
- DCHECK_NE(window(), x11::None);
+ DCHECK_NE(window(), x11::Window::None);
DCHECK(event);
DCHECK(current_xevent_);
@@ -567,7 +596,7 @@ uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
return POST_DISPATCH_STOP_PROPAGATION;
}
-void X11Window::DispatchUiEvent(ui::Event* event, XEvent* xev) {
+void X11Window::DispatchUiEvent(ui::Event* event, x11::Event* xev) {
auto* window_manager = X11WindowManager::GetInstance();
DCHECK(window_manager);
@@ -595,7 +624,7 @@ void X11Window::DispatchUiEvent(ui::Event* event, XEvent* xev) {
return located_events_grabber->DispatchUiEvent(event, xev);
}
- XEvent last_xev;
+ x11::Event last_xev;
std::unique_ptr<ui::Event> last_motion;
bool coalesced = CoalesceEventsIfNeeded(xev, event->type(), &last_xev);
if (coalesced) {
@@ -619,9 +648,6 @@ void X11Window::DispatchUiEvent(ui::Event* event, XEvent* xev) {
platform_window_delegate_->DispatchEvent(event);
#endif
}
-
- if (coalesced)
- XFreeEventData(last_xev.xgeneric.display, &last_xev.xcookie);
}
void X11Window::OnXWindowCreated() {
@@ -640,10 +666,6 @@ void X11Window::OnXWindowCreated() {
platform_window_delegate_->OnAcceleratedWidgetAvailable(GetWidget());
}
-bool X11Window::DispatchDraggingUiEvent(ui::Event* event) {
- return false;
-}
-
void X11Window::OnXWindowStateChanged() {
// Determine the new window state information to be propagated to the client.
// Note that the order of checks is important here, because window can have
@@ -728,14 +750,22 @@ void X11Window::OnXWindowLostPointerGrab() {
x11_extension_delegate_->OnLostMouseGrab();
}
-void X11Window::OnXWindowSelectionEvent(XEvent* xev) {
+void X11Window::OnXWindowSelectionEvent(x11::Event* xev) {
if (x_event_delegate_)
x_event_delegate_->OnXWindowSelectionEvent(xev);
+#if defined(USE_OZONE)
+ DCHECK(drag_drop_client_);
+ drag_drop_client_->OnSelectionNotify(*xev->As<x11::SelectionNotifyEvent>());
+#endif
}
-void X11Window::OnXWindowDragDropEvent(XEvent* xev) {
+void X11Window::OnXWindowDragDropEvent(x11::Event* xev) {
if (x_event_delegate_)
x_event_delegate_->OnXWindowDragDropEvent(xev);
+#if defined(USE_OZONE)
+ DCHECK(drag_drop_client_);
+ drag_drop_client_->HandleXdndEvent(*xev->As<x11::ClientMessageEvent>());
+#endif
}
base::Optional<gfx::Size> X11Window::GetMinimumSizeForXWindow() {
@@ -766,6 +796,136 @@ void X11Window::EndMoveLoop() {
x11_window_move_client_->EndMoveLoop();
}
+#if defined(USE_OZONE)
+void X11Window::StartDrag(const OSExchangeData& data,
+ int operation,
+ gfx::NativeCursor cursor,
+ WmDragHandler::Delegate* delegate) {
+ DCHECK(drag_drop_client_);
+ DCHECK(!drag_handler_delegate_);
+
+ drag_handler_delegate_ = delegate;
+ drag_drop_client_->InitDrag(operation, &data);
+ drag_operation_ = 0;
+ notified_enter_ = false;
+
+ SetCapture();
+
+ dragging_ = true;
+}
+
+std::unique_ptr<XTopmostWindowFinder> X11Window::CreateWindowFinder() {
+ return std::make_unique<X11TopmostWindowFinder>();
+}
+
+int X11Window::UpdateDrag(const gfx::Point& screen_point) {
+ WmDropHandler* drop_handler = GetWmDropHandler(*this);
+ if (!drop_handler)
+ return DragDropTypes::DRAG_NONE;
+ if (!notified_enter_) {
+ DCHECK(drag_drop_client_);
+ auto* target_current_context = drag_drop_client_->target_current_context();
+ DCHECK(target_current_context);
+ drop_handler->OnDragEnter(
+ gfx::PointF(screen_point),
+ std::make_unique<ui::OSExchangeData>(
+ std::make_unique<ui::XOSExchangeDataProvider>(
+ drag_drop_client_->xwindow(),
+ target_current_context->fetched_targets())),
+ ui::DragDropTypes::DRAG_COPY);
+ notified_enter_ = true;
+ }
+
+ drag_operation_ = drop_handler->OnDragMotion(gfx::PointF(screen_point),
+ ui::DragDropTypes::DRAG_COPY);
+ return drag_operation_;
+}
+
+void X11Window::UpdateCursor(
+ DragDropTypes::DragOperation negotiated_operation) {
+ DCHECK(drag_handler_delegate_);
+ drag_handler_delegate_->OnDragOperationChanged(negotiated_operation);
+}
+
+void X11Window::OnBeginForeignDrag(x11::Window window) {
+ NOTIMPLEMENTED_LOG_ONCE();
+}
+
+void X11Window::OnEndForeignDrag() {
+ NOTIMPLEMENTED_LOG_ONCE();
+}
+
+void X11Window::OnBeforeDragLeave() {
+ WmDropHandler* drop_handler = GetWmDropHandler(*this);
+ if (!drop_handler)
+ return;
+ drop_handler->OnDragLeave();
+ notified_enter_ = false;
+}
+
+int X11Window::PerformDrop() {
+ WmDropHandler* drop_handler = GetWmDropHandler(*this);
+ if (!drop_handler)
+ return DragDropTypes::DRAG_NONE;
+
+ DCHECK(notified_enter_);
+
+ // The drop data has been supplied on entering the window. The drop handler
+ // should have it since then.
+ drop_handler->OnDragDrop({});
+ notified_enter_ = false;
+ return drag_operation_;
+}
+
+void X11Window::EndDragLoop() {
+ DCHECK(drag_handler_delegate_);
+ drag_handler_delegate_->OnDragFinished(drag_operation_);
+ drag_handler_delegate_ = nullptr;
+}
+#endif // defined(USE_OZONE)
+
+bool X11Window::DispatchDraggingUiEvent(Event* event) {
+#if defined(USE_OZONE)
+ // Drag and drop have a priority over other processing.
+ if (dragging_) {
+ DCHECK(drag_drop_client_);
+
+ switch (event->type()) {
+ case ET_MOUSE_MOVED:
+ case ET_MOUSE_DRAGGED: {
+ drag_handler_delegate_->OnDragLocationChanged(
+ event->AsLocatedEvent()->root_location());
+ drag_drop_client_->HandleMouseMovement(
+ event->AsLocatedEvent()->root_location(),
+ event->AsMouseEvent()->flags(),
+ event->AsMouseEvent()->time_stamp());
+ return true;
+ }
+ case ET_MOUSE_RELEASED:
+ if (!event->AsMouseEvent()->IsLeftMouseButton())
+ break;
+ // Assume that drags are being done with the left mouse button. Only
+ // break the drag if the left mouse button was released.
+ drag_drop_client_->HandleMouseReleased();
+ dragging_ = false;
+ ReleaseCapture();
+ return true;
+ case ET_KEY_PRESSED:
+ if (event->AsKeyEvent()->key_code() != VKEY_ESCAPE)
+ break;
+ EndMoveLoop();
+ drag_drop_client_->HandleMoveLoopEnded();
+ dragging_ = false;
+ ReleaseCapture();
+ return true;
+ default:
+ break;
+ }
+ }
+#endif // defined(USE_OZONE)
+ return false;
+}
+
gfx::Size X11Window::AdjustSizeForDisplay(
const gfx::Size& requested_size_in_pixels) {
#if defined(OS_CHROMEOS)
@@ -795,7 +955,7 @@ gfx::Size X11Window::AdjustSizeForDisplay(
void X11Window::ConvertEventLocationToTargetLocation(
const gfx::Rect& target_window_bounds,
const gfx::Rect& current_window_bounds,
- ui::LocatedEvent* located_event) {
+ LocatedEvent* located_event) {
// TODO(msisov): for ozone, we need to access PlatformScreen instead and get
// the displays.
auto* display = display::Screen::GetScreen();
diff --git a/chromium/ui/platform_window/x11/x11_window.h b/chromium/ui/platform_window/x11/x11_window.h
index 378512c1676..011fbee55c3 100644
--- a/chromium/ui/platform_window/x11/x11_window.h
+++ b/chromium/ui/platform_window/x11/x11_window.h
@@ -9,6 +9,7 @@
#include "ui/base/x/x11_window.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/gfx/x/event.h"
#include "ui/platform_window/extensions/workspace_extension.h"
#include "ui/platform_window/extensions/x11_extension.h"
#include "ui/platform_window/platform_window.h"
@@ -17,26 +18,32 @@
#include "ui/platform_window/platform_window_init_properties.h"
#include "ui/platform_window/x11/x11_window_export.h"
+#if defined(USE_OZONE)
+#include "ui/base/x/x11_drag_drop_client.h"
+#include "ui/platform_window/platform_window_handler/wm_drag_handler.h"
+#endif
+
namespace ui {
+class PlatformWindowDelegate;
class X11ExtensionDelegate;
class X11DesktopWindowMoveClient;
class LocatedEvent;
class WorkspaceExtensionDelegate;
// Delegate interface used to communicate the X11PlatformWindow API client about
-// XEvents of interest.
+// x11::Events of interest.
class X11_WINDOW_EXPORT XEventDelegate {
public:
- virtual ~XEventDelegate() {}
+ virtual ~XEventDelegate() = default;
// TODO(crbug.com/990756): We need to implement/reuse ozone interface for
// these.
- virtual void OnXWindowSelectionEvent(XEvent* xev) = 0;
- virtual void OnXWindowDragDropEvent(XEvent* xev) = 0;
+ virtual void OnXWindowSelectionEvent(x11::Event* xev) = 0;
+ virtual void OnXWindowDragDropEvent(x11::Event* xev) = 0;
};
-// PlatformWindow implementation for X11. PlatformEvents are XEvents.
+// PlatformWindow implementation for X11.
class X11_WINDOW_EXPORT X11Window : public PlatformWindow,
public WmMoveResizeHandler,
public XWindow,
@@ -44,6 +51,10 @@ class X11_WINDOW_EXPORT X11Window : public PlatformWindow,
public XEventDispatcher,
public WorkspaceExtension,
public X11Extension,
+#if defined(USE_OZONE)
+ public WmDragHandler,
+ public XDragDropClient::Delegate,
+#endif
public WmMoveLoopHandler {
public:
explicit X11Window(PlatformWindowDelegate* platform_window_delegate);
@@ -120,10 +131,10 @@ class X11_WINDOW_EXPORT X11Window : public PlatformWindow,
void SetX11ExtensionDelegate(X11ExtensionDelegate* delegate) override;
// Overridden from ui::XEventDispatcher:
- void CheckCanDispatchNextPlatformEvent(XEvent* xev) override;
+ void CheckCanDispatchNextPlatformEvent(x11::Event* xev) override;
void PlatformEventDispatchFinished() override;
PlatformEventDispatcher* GetPlatformEventDispatcher() override;
- bool DispatchXEvent(XEvent* event) override;
+ bool DispatchXEvent(x11::Event* event) override;
protected:
PlatformWindowDelegate* platform_window_delegate() const {
@@ -145,8 +156,8 @@ class X11_WINDOW_EXPORT X11Window : public PlatformWindow,
void OnXWindowIsActiveChanged(bool active) override;
void OnXWindowWorkspaceChanged() override;
void OnXWindowLostPointerGrab() override;
- void OnXWindowSelectionEvent(XEvent* xev) override;
- void OnXWindowDragDropEvent(XEvent* xev) override;
+ void OnXWindowSelectionEvent(x11::Event* xev) override;
+ void OnXWindowDragDropEvent(x11::Event* xev) override;
base::Optional<gfx::Size> GetMinimumSizeForXWindow() override;
base::Optional<gfx::Size> GetMaximumSizeForXWindow() override;
void GetWindowMaskForXWindow(const gfx::Size& size,
@@ -157,7 +168,7 @@ class X11_WINDOW_EXPORT X11Window : public PlatformWindow,
bool CanDispatchEvent(const PlatformEvent& event) override;
uint32_t DispatchEvent(const PlatformEvent& event) override;
- void DispatchUiEvent(ui::Event* event, XEvent* xev);
+ void DispatchUiEvent(ui::Event* event, x11::Event* xev);
// WmMoveResizeHandler
void DispatchHostWindowDragMovement(
@@ -168,8 +179,27 @@ class X11_WINDOW_EXPORT X11Window : public PlatformWindow,
bool RunMoveLoop(const gfx::Vector2d& drag_offset) override;
void EndMoveLoop() override;
+#if defined(USE_OZONE)
+ // WmDragHandler
+ void StartDrag(const ui::OSExchangeData& data,
+ int operation,
+ gfx::NativeCursor cursor,
+ WmDragHandler::Delegate* delegate) override;
+
+ // ui::XDragDropClient::Delegate
+ std::unique_ptr<ui::XTopmostWindowFinder> CreateWindowFinder() override;
+ int UpdateDrag(const gfx::Point& screen_point) override;
+ void UpdateCursor(
+ ui::DragDropTypes::DragOperation negotiated_operation) override;
+ void OnBeginForeignDrag(x11::Window window) override;
+ void OnEndForeignDrag() override;
+ void OnBeforeDragLeave() override;
+ int PerformDrop() override;
+ void EndDragLoop() override;
+#endif // defined(USE_OZONE)
+
// Handles |xevent| as a Atk Key Event
- bool HandleAsAtkEvent(XEvent* xevent);
+ bool HandleAsAtkEvent(x11::Event* xevent);
// Adjusts |requested_size_in_pixels| to avoid the WM "feature" where setting
// the window size to the monitor size causes the WM to set the EWMH for
@@ -205,12 +235,25 @@ class X11_WINDOW_EXPORT X11Window : public PlatformWindow,
gfx::Rect restored_bounds_in_pixels_;
// Tells if this dispatcher can process next translated event based on a
- // previous check in ::CheckCanDispatchNextPlatformEvent based on a XID
- // target.
- XEvent* current_xevent_ = nullptr;
+ // previous check in ::CheckCanDispatchNextPlatformEvent based on a
+ // x11::Window target.
+ x11::Event* current_xevent_ = nullptr;
std::unique_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
+#if defined(USE_OZONE)
+ // True while the drag initiated in this window is in progress.
+ bool dragging_ = false;
+ // Whether the drop handler has notified that the drag has entered.
+ bool notified_enter_ = false;
+ // Keeps the last negotiated operation returned by the drop handler.
+ int drag_operation_ = 0;
+
+ // Handles XDND events going through this window.
+ std::unique_ptr<XDragDropClient> drag_drop_client_;
+ WmDragHandler::Delegate* drag_handler_delegate_ = nullptr;
+#endif // defined(USE_OZONE)
+
DISALLOW_COPY_AND_ASSIGN(X11Window);
};