| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" | 5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" |
| 6 | 6 |
| 7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
| 8 | 8 |
| 9 #include "base/event_types.h" | 9 #include "base/event_types.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "ui/aura/window.h" | 12 #include "ui/aura/window.h" |
| 13 #include "ui/aura/window_tree_host.h" | 13 #include "ui/aura/window_tree_host.h" |
| 14 #include "ui/base/clipboard/clipboard.h" | 14 #include "ui/base/clipboard/clipboard.h" |
| 15 #include "ui/base/dragdrop/drag_drop_types.h" | 15 #include "ui/base/dragdrop/drag_drop_types.h" |
| 16 #include "ui/base/dragdrop/drop_target_event.h" | 16 #include "ui/base/dragdrop/drop_target_event.h" |
| 17 #include "ui/base/dragdrop/os_exchange_data.h" | 17 #include "ui/base/dragdrop/os_exchange_data.h" |
| 18 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" | 18 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" |
| 19 #include "ui/base/x/selection_utils.h" | 19 #include "ui/base/x/selection_utils.h" |
| 20 #include "ui/base/x/x11_util.h" | 20 #include "ui/base/x/x11_util.h" |
| 21 #include "ui/events/event.h" | 21 #include "ui/events/event.h" |
| 22 #include "ui/events/platform/platform_event_source.h" | 22 #include "ui/events/platform/platform_event_source.h" |
| 23 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" | 23 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" |
| 24 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h" |
| 24 #include "ui/wm/public/drag_drop_client.h" | 25 #include "ui/wm/public/drag_drop_client.h" |
| 25 #include "ui/wm/public/drag_drop_delegate.h" | 26 #include "ui/wm/public/drag_drop_delegate.h" |
| 26 | 27 |
| 27 using aura::client::DragDropDelegate; | 28 using aura::client::DragDropDelegate; |
| 28 using ui::OSExchangeData; | 29 using ui::OSExchangeData; |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| 32 const int kMinXdndVersion = 5; | 33 const int kMinXdndVersion = 5; |
| 33 | 34 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 57 "XdndDrop", | 58 "XdndDrop", |
| 58 "XdndEnter", | 59 "XdndEnter", |
| 59 "XdndFinished", | 60 "XdndFinished", |
| 60 "XdndLeave", | 61 "XdndLeave", |
| 61 "XdndPosition", | 62 "XdndPosition", |
| 62 "XdndProxy", // Proxy windows? | 63 "XdndProxy", // Proxy windows? |
| 63 kXdndSelection, | 64 kXdndSelection, |
| 64 "XdndStatus", | 65 "XdndStatus", |
| 65 "XdndTypeList", | 66 "XdndTypeList", |
| 66 ui::Clipboard::kMimeTypeText, | 67 ui::Clipboard::kMimeTypeText, |
| 67 "_NET_WM_WINDOW_TYPE_MENU", | |
| 68 NULL | 68 NULL |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 // The time to wait for the target to respond after the user has released the | 71 // The time to wait for the target to respond after the user has released the |
| 72 // mouse button before ending the move loop. | 72 // mouse button before ending the move loop. |
| 73 const int kEndMoveLoopTimeoutMs = 1000; | 73 const int kEndMoveLoopTimeoutMs = 1000; |
| 74 | 74 |
| 75 static base::LazyInstance< | 75 static base::LazyInstance< |
| 76 std::map< ::Window, views::DesktopDragDropClientAuraX11*> >::Leaky | 76 std::map< ::Window, views::DesktopDragDropClientAuraX11*> >::Leaky |
| 77 g_live_client_map = LAZY_INSTANCE_INITIALIZER; | 77 g_live_client_map = LAZY_INSTANCE_INITIALIZER; |
| 78 | 78 |
| 79 // Helper class to FindWindowFor which looks for a drag target under the | |
| 80 // cursor. | |
| 81 class DragTargetWindowFinder : public ui::EnumerateWindowsDelegate { | |
| 82 public: | |
| 83 DragTargetWindowFinder(XID ignored_icon_window, | |
| 84 Atom menu_type_atom, | |
| 85 gfx::Point screen_loc) | |
| 86 : ignored_icon_window_(ignored_icon_window), | |
| 87 output_window_(None), | |
| 88 menu_type_atom_(menu_type_atom), | |
| 89 screen_loc_(screen_loc) { | |
| 90 ui::EnumerateTopLevelWindows(this); | |
| 91 } | |
| 92 | |
| 93 virtual ~DragTargetWindowFinder() {} | |
| 94 | |
| 95 XID window() const { return output_window_; } | |
| 96 | |
| 97 protected: | |
| 98 virtual bool ShouldStopIterating(XID window) OVERRIDE { | |
| 99 if (window == ignored_icon_window_) | |
| 100 return false; | |
| 101 | |
| 102 if (!ui::IsWindowVisible(window)) | |
| 103 return false; | |
| 104 | |
| 105 if (!ui::WindowContainsPoint(window, screen_loc_)) | |
| 106 return false; | |
| 107 | |
| 108 int value = 0; | |
| 109 if (ui::PropertyExists(window, "WM_STATE") || | |
| 110 (ui::GetIntProperty(window, "_NET_WM_WINDOW_TYPE", &value) && | |
| 111 static_cast<Atom>(value) == menu_type_atom_)) { | |
| 112 output_window_ = window; | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 return false; | |
| 117 } | |
| 118 | |
| 119 private: | |
| 120 XID ignored_icon_window_; | |
| 121 XID output_window_; | |
| 122 const Atom menu_type_atom_; | |
| 123 gfx::Point screen_loc_; | |
| 124 | |
| 125 DISALLOW_COPY_AND_ASSIGN(DragTargetWindowFinder); | |
| 126 }; | |
| 127 | |
| 128 // Returns the topmost X11 window at |screen_point| if it is advertising that | 79 // Returns the topmost X11 window at |screen_point| if it is advertising that |
| 129 // is supports the Xdnd protocol. Will return the window under the pointer as | 80 // is supports the Xdnd protocol. Will return the window under the pointer as |
| 130 // |mouse_window|. If there's a Xdnd aware window, it will be returned in | 81 // |mouse_window|. If there's a Xdnd aware window, it will be returned in |
| 131 // |dest_window|. | 82 // |dest_window|. |
| 132 void FindWindowFor(const gfx::Point& screen_point, | 83 void FindWindowFor(const gfx::Point& screen_point, |
| 133 ::Window* mouse_window, ::Window* dest_window, | 84 ::Window* mouse_window, |
| 134 Atom menu_type_atom) { | 85 ::Window* dest_window) { |
| 135 DragTargetWindowFinder finder(None, menu_type_atom, screen_point); | 86 views::X11TopmostWindowFinder finder; |
| 136 *mouse_window = finder.window(); | 87 *mouse_window = finder.FindWindowAt(screen_point); |
| 137 *dest_window = None; | 88 *dest_window = None; |
| 138 | 89 |
| 139 if (finder.window() == None) | 90 if (*mouse_window == None) |
| 140 return; | 91 return; |
| 141 | 92 |
| 142 // Figure out which window we should test as XdndAware. If mouse_window has | 93 // Figure out which window we should test as XdndAware. If mouse_window has |
| 143 // XdndProxy, it will set that proxy on target, and if not, |target|'s | 94 // XdndProxy, it will set that proxy on target, and if not, |target|'s |
| 144 // original value will remain. | 95 // original value will remain. |
| 145 XID target = *mouse_window; | 96 XID target = *mouse_window; |
| 146 ui::GetXIDProperty(*mouse_window, "XdndProxy", &target); | 97 ui::GetXIDProperty(*mouse_window, "XdndProxy", &target); |
| 147 | 98 |
| 148 int version; | 99 int version; |
| 149 if (ui::GetIntProperty(target, "XdndAware", &version) && | 100 if (ui::GetIntProperty(target, "XdndAware", &version) && |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 | 663 |
| 713 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) { | 664 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) { |
| 714 gfx::Point screen_point(event->x_root, event->y_root); | 665 gfx::Point screen_point(event->x_root, event->y_root); |
| 715 | 666 |
| 716 if (source_state_ != SOURCE_STATE_OTHER) | 667 if (source_state_ != SOURCE_STATE_OTHER) |
| 717 return; | 668 return; |
| 718 | 669 |
| 719 // Find the current window the cursor is over. | 670 // Find the current window the cursor is over. |
| 720 ::Window mouse_window = None; | 671 ::Window mouse_window = None; |
| 721 ::Window dest_window = None; | 672 ::Window dest_window = None; |
| 722 FindWindowFor(screen_point, &mouse_window, &dest_window, | 673 FindWindowFor(screen_point, &mouse_window, &dest_window); |
| 723 atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_MENU")); | |
| 724 | 674 |
| 725 if (source_current_window_ != dest_window) { | 675 if (source_current_window_ != dest_window) { |
| 726 if (source_current_window_ != None) | 676 if (source_current_window_ != None) |
| 727 SendXdndLeave(source_current_window_); | 677 SendXdndLeave(source_current_window_); |
| 728 | 678 |
| 729 source_current_window_ = dest_window; | 679 source_current_window_ = dest_window; |
| 730 | 680 |
| 731 if (source_current_window_ != None) { | 681 if (source_current_window_ != None) { |
| 732 negotiated_operation_.erase(source_current_window_); | 682 negotiated_operation_.erase(source_current_window_); |
| 733 SendXdndEnter(source_current_window_); | 683 SendXdndEnter(source_current_window_); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 // GdkEvent about the failed drag. (And sending this message doesn't appear | 993 // GdkEvent about the failed drag. (And sending this message doesn't appear |
| 1044 // to go through normal xlib machinery, but instead passes through the low | 994 // to go through normal xlib machinery, but instead passes through the low |
| 1045 // level xProto (the x11 wire format) that I don't understand. | 995 // level xProto (the x11 wire format) that I don't understand. |
| 1046 // | 996 // |
| 1047 // I'm unsure if I have to jump through those hoops, or if XSendEvent is | 997 // I'm unsure if I have to jump through those hoops, or if XSendEvent is |
| 1048 // sufficient. | 998 // sufficient. |
| 1049 XSendEvent(xdisplay_, xid, False, 0, xev); | 999 XSendEvent(xdisplay_, xid, False, 0, xev); |
| 1050 } | 1000 } |
| 1051 | 1001 |
| 1052 } // namespace views | 1002 } // namespace views |
| OLD | NEW |