| Index: ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
|
| diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
|
| index b2d4eedb489ac6b696c2e3eb08733f82944d1c77..10d6f9594d2239a987c727c96722070f719cd74c 100644
|
| --- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
|
| +++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
|
| @@ -80,33 +80,6 @@ static base::LazyInstance<
|
| std::map< ::Window, views::DesktopDragDropClientAuraX11*> >::Leaky
|
| g_live_client_map = LAZY_INSTANCE_INITIALIZER;
|
|
|
| -// Returns the topmost X11 window at |screen_point| if it is advertising that
|
| -// is supports the Xdnd protocol. Will return the window under the pointer as
|
| -// |mouse_window|. If there's a Xdnd aware window, it will be returned in
|
| -// |dest_window|.
|
| -void FindWindowFor(const gfx::Point& screen_point,
|
| - ::Window* mouse_window,
|
| - ::Window* dest_window) {
|
| - views::X11TopmostWindowFinder finder;
|
| - *mouse_window = finder.FindWindowAt(screen_point);
|
| - *dest_window = None;
|
| -
|
| - if (*mouse_window == None)
|
| - return;
|
| -
|
| - // Figure out which window we should test as XdndAware. If mouse_window has
|
| - // XdndProxy, it will set that proxy on target, and if not, |target|'s
|
| - // original value will remain.
|
| - XID target = *mouse_window;
|
| - ui::GetXIDProperty(*mouse_window, "XdndProxy", &target);
|
| -
|
| - int version;
|
| - if (ui::GetIntProperty(target, "XdndAware", &version) &&
|
| - version >= kMinXdndVersion) {
|
| - *dest_window = target;
|
| - }
|
| -}
|
| -
|
| } // namespace
|
|
|
| namespace views {
|
| @@ -536,6 +509,13 @@ void DesktopDragDropClientAuraX11::OnXdndStatus(
|
| void DesktopDragDropClientAuraX11::OnXdndFinished(
|
| const XClientMessageEvent& event) {
|
| DVLOG(1) << "XdndFinished";
|
| + unsigned long source_window = event.data.l[0];
|
| + if (source_current_window_ != source_window)
|
| + return;
|
| +
|
| + // Clear |negotiated_operation_| if the drag was rejected.
|
| + if ((event.data.l[1] & 1) == 0)
|
| + negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
|
|
|
| // Clear |source_current_window_| to avoid sending XdndLeave upon ending the
|
| // move loop.
|
| @@ -731,6 +711,68 @@ void DesktopDragDropClientAuraX11::OnMoveLoopEnded() {
|
| end_move_loop_timer_.Stop();
|
| }
|
|
|
| +XID DesktopDragDropClientAuraX11::FindWindowFor(
|
| + const gfx::Point& screen_point) {
|
| + views::X11TopmostWindowFinder finder;
|
| + ::Window target = finder.FindWindowAt(screen_point);
|
| +
|
| + if (target == None)
|
| + return None;
|
| +
|
| + // Figure out which window we should test as XdndAware. If mouse_window has
|
| + // XdndProxy, it will set that proxy on target, and if not, |target|'s
|
| + // original value will remain.
|
| + ui::GetXIDProperty(target, "XdndProxy", &target);
|
| +
|
| + int version;
|
| + if (ui::GetIntProperty(target, "XdndAware", &version) &&
|
| + version >= kMinXdndVersion) {
|
| + return target;
|
| + }
|
| + return None;
|
| +}
|
| +
|
| +void DesktopDragDropClientAuraX11::SendXClientEvent(::Window xid,
|
| + XEvent* xev) {
|
| + DCHECK_EQ(ClientMessage, xev->type);
|
| +
|
| + // Don't send messages to the X11 message queue if we can help it.
|
| + DesktopDragDropClientAuraX11* short_circuit = GetForWindow(xid);
|
| + if (short_circuit) {
|
| + Atom message_type = xev->xclient.message_type;
|
| + if (message_type == atom_cache_.GetAtom("XdndEnter")) {
|
| + short_circuit->OnXdndEnter(xev->xclient);
|
| + return;
|
| + } else if (message_type == atom_cache_.GetAtom("XdndLeave")) {
|
| + short_circuit->OnXdndLeave(xev->xclient);
|
| + return;
|
| + } else if (message_type == atom_cache_.GetAtom("XdndPosition")) {
|
| + short_circuit->OnXdndPosition(xev->xclient);
|
| + return;
|
| + } else if (message_type == atom_cache_.GetAtom("XdndStatus")) {
|
| + short_circuit->OnXdndStatus(xev->xclient);
|
| + return;
|
| + } else if (message_type == atom_cache_.GetAtom("XdndFinished")) {
|
| + short_circuit->OnXdndFinished(xev->xclient);
|
| + return;
|
| + } else if (message_type == atom_cache_.GetAtom("XdndDrop")) {
|
| + short_circuit->OnXdndDrop(xev->xclient);
|
| + return;
|
| + }
|
| + }
|
| +
|
| + // I don't understand why the GTK+ code is doing what it's doing here. It
|
| + // goes out of its way to send the XEvent so that it receives a callback on
|
| + // success or failure, and when it fails, it then sends an internal
|
| + // GdkEvent about the failed drag. (And sending this message doesn't appear
|
| + // to go through normal xlib machinery, but instead passes through the low
|
| + // level xProto (the x11 wire format) that I don't understand.
|
| + //
|
| + // I'm unsure if I have to jump through those hoops, or if XSendEvent is
|
| + // sufficient.
|
| + XSendEvent(xdisplay_, xid, False, 0, xev);
|
| +}
|
| +
|
| void DesktopDragDropClientAuraX11::ProcessMouseMove(
|
| const gfx::Point& screen_point,
|
| unsigned long event_time) {
|
| @@ -738,9 +780,7 @@ void DesktopDragDropClientAuraX11::ProcessMouseMove(
|
| return;
|
|
|
| // Find the current window the cursor is over.
|
| - ::Window mouse_window = None;
|
| - ::Window dest_window = None;
|
| - FindWindowFor(screen_point, &mouse_window, &dest_window);
|
| + ::Window dest_window = FindWindowFor(screen_point);
|
|
|
| if (source_current_window_ != dest_window) {
|
| if (source_current_window_ != None)
|
| @@ -988,45 +1028,4 @@ void DesktopDragDropClientAuraX11::SendXdndDrop(::Window dest_window) {
|
| SendXClientEvent(dest_window, &xev);
|
| }
|
|
|
| -void DesktopDragDropClientAuraX11::SendXClientEvent(::Window xid,
|
| - XEvent* xev) {
|
| - DCHECK_EQ(ClientMessage, xev->type);
|
| -
|
| - // Don't send messages to the X11 message queue if we can help it.
|
| - DesktopDragDropClientAuraX11* short_circuit = GetForWindow(xid);
|
| - if (short_circuit) {
|
| - Atom message_type = xev->xclient.message_type;
|
| - if (message_type == atom_cache_.GetAtom("XdndEnter")) {
|
| - short_circuit->OnXdndEnter(xev->xclient);
|
| - return;
|
| - } else if (message_type == atom_cache_.GetAtom("XdndLeave")) {
|
| - short_circuit->OnXdndLeave(xev->xclient);
|
| - return;
|
| - } else if (message_type == atom_cache_.GetAtom("XdndPosition")) {
|
| - short_circuit->OnXdndPosition(xev->xclient);
|
| - return;
|
| - } else if (message_type == atom_cache_.GetAtom("XdndStatus")) {
|
| - short_circuit->OnXdndStatus(xev->xclient);
|
| - return;
|
| - } else if (message_type == atom_cache_.GetAtom("XdndFinished")) {
|
| - short_circuit->OnXdndFinished(xev->xclient);
|
| - return;
|
| - } else if (message_type == atom_cache_.GetAtom("XdndDrop")) {
|
| - short_circuit->OnXdndDrop(xev->xclient);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - // I don't understand why the GTK+ code is doing what it's doing here. It
|
| - // goes out of its way to send the XEvent so that it receives a callback on
|
| - // success or failure, and when it fails, it then sends an internal
|
| - // GdkEvent about the failed drag. (And sending this message doesn't appear
|
| - // to go through normal xlib machinery, but instead passes through the low
|
| - // level xProto (the x11 wire format) that I don't understand.
|
| - //
|
| - // I'm unsure if I have to jump through those hoops, or if XSendEvent is
|
| - // sufficient.
|
| - XSendEvent(xdisplay_, xid, False, 0, xev);
|
| -}
|
| -
|
| } // namespace views
|
|
|