Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc

Issue 260263002: Merge three implementations for getting the topmost x11 window at a point (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698