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

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

Issue 196213004: Allows menu host windows to be enumerated in DragTargetWindowFinder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Implements menu XID caching and dispatches mouse drags in a posted task (test) Created 6 years, 9 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
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"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 "XdndAware", 51 "XdndAware",
52 "XdndDrop", 52 "XdndDrop",
53 "XdndEnter", 53 "XdndEnter",
54 "XdndFinished", 54 "XdndFinished",
55 "XdndLeave", 55 "XdndLeave",
56 "XdndPosition", 56 "XdndPosition",
57 "XdndProxy", // Proxy windows? 57 "XdndProxy", // Proxy windows?
58 kXdndSelection, 58 kXdndSelection,
59 "XdndStatus", 59 "XdndStatus",
60 "XdndTypeList", 60 "XdndTypeList",
61 "_NET_WM_WINDOW_TYPE_MENU",
61 NULL 62 NULL
62 }; 63 };
63 64
64 // The time to wait for the target to respond after the user has released the 65 // The time to wait for the target to respond after the user has released the
65 // mouse button before ending the move loop. 66 // mouse button before ending the move loop.
66 const int kEndMoveLoopTimeoutMs = 30000; 67 const int kEndMoveLoopTimeoutMs = 30000;
67 68
68 static base::LazyInstance< 69 static base::LazyInstance<
69 std::map< ::Window, views::DesktopDragDropClientAuraX11*> >::Leaky 70 std::map< ::Window, views::DesktopDragDropClientAuraX11*> >::Leaky
70 g_live_client_map = LAZY_INSTANCE_INITIALIZER; 71 g_live_client_map = LAZY_INSTANCE_INITIALIZER;
71 72
72 // Helper class to FindWindowFor which looks for a drag target under the 73 // Helper class to FindWindowFor which looks for a drag target under the
73 // cursor. 74 // cursor.
74 class DragTargetWindowFinder : public ui::EnumerateWindowsDelegate { 75 class DragTargetWindowFinder : public ui::EnumerateWindowsDelegate {
75 public: 76 public:
76 DragTargetWindowFinder(XID ignored_icon_window, 77 DragTargetWindowFinder(XID ignored_icon_window,
78 Atom menu_type_atom,
77 gfx::Point screen_loc) 79 gfx::Point screen_loc)
78 : ignored_icon_window_(ignored_icon_window), 80 : ignored_icon_window_(ignored_icon_window),
79 output_window_(None), 81 output_window_(None),
82 menu_type_atom_(menu_type_atom),
80 screen_loc_(screen_loc) { 83 screen_loc_(screen_loc) {
81 ui::EnumerateTopLevelWindows(this); 84 ui::EnumerateTopLevelWindows(this);
82 } 85 }
83 86
84 virtual ~DragTargetWindowFinder() {} 87 virtual ~DragTargetWindowFinder() {}
85 88
86 XID window() const { return output_window_; } 89 XID window() const { return output_window_; }
87 90
88 protected: 91 protected:
89 virtual bool ShouldStopIterating(XID window) OVERRIDE { 92 virtual bool ShouldStopIterating(XID window) OVERRIDE {
90 if (window == ignored_icon_window_) 93 if (window == ignored_icon_window_)
91 return false; 94 return false;
92 95
93 if (!ui::IsWindowVisible(window)) 96 if (!ui::IsWindowVisible(window))
94 return false; 97 return false;
95 98
96 if (!ui::WindowContainsPoint(window, screen_loc_)) 99 if (!ui::WindowContainsPoint(window, screen_loc_))
97 return false; 100 return false;
98 101
99 if (ui::PropertyExists(window, "WM_STATE")) { 102 int value = 0;
103 if (ui::PropertyExists(window, "WM_STATE") ||
104 (ui::GetIntProperty(window, "_NET_WM_WINDOW_TYPE", &value) &&
105 static_cast<Atom>(value) == menu_type_atom_)) {
100 output_window_ = window; 106 output_window_ = window;
101 return true; 107 return true;
102 } 108 }
103 109
104 return false; 110 return false;
105 } 111 }
106 112
107 private: 113 private:
108 XID ignored_icon_window_; 114 XID ignored_icon_window_;
109 XID output_window_; 115 XID output_window_;
116 const Atom menu_type_atom_;
110 gfx::Point screen_loc_; 117 gfx::Point screen_loc_;
111 118
112 DISALLOW_COPY_AND_ASSIGN(DragTargetWindowFinder); 119 DISALLOW_COPY_AND_ASSIGN(DragTargetWindowFinder);
113 }; 120 };
114 121
115 // Returns the topmost X11 window at |screen_point| if it is advertising that 122 // Returns the topmost X11 window at |screen_point| if it is advertising that
116 // is supports the Xdnd protocol. Will return the window under the pointer as 123 // is supports the Xdnd protocol. Will return the window under the pointer as
117 // |mouse_window|. If there's a Xdnd aware window, it will be returned in 124 // |mouse_window|. If there's a Xdnd aware window, it will be returned in
118 // |dest_window|. 125 // |dest_window|.
119 void FindWindowFor(const gfx::Point& screen_point, 126 void FindWindowFor(const gfx::Point& screen_point,
120 ::Window* mouse_window, ::Window* dest_window) { 127 ::Window* mouse_window, ::Window* dest_window,
121 DragTargetWindowFinder finder(None, screen_point); 128 Atom menu_type_atom) {
129 DragTargetWindowFinder finder(None, menu_type_atom, screen_point);
122 *mouse_window = finder.window(); 130 *mouse_window = finder.window();
123 *dest_window = None; 131 *dest_window = None;
124 132
125 if (finder.window() == None) 133 if (finder.window() == None)
126 return; 134 return;
127 135
128 // Figure out which window we should test as XdndAware. If mouse_window has 136 // Figure out which window we should test as XdndAware. If mouse_window has
129 // XdndProxy, it will set that proxy on target, and if not, |target|'s 137 // XdndProxy, it will set that proxy on target, and if not, |target|'s
130 // original value will remain. 138 // original value will remain.
131 XID target = *mouse_window; 139 XID target = *mouse_window;
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 429
422 // Mark that we are aware of drag and drop concepts. 430 // Mark that we are aware of drag and drop concepts.
423 unsigned long xdnd_version = kMinXdndVersion; 431 unsigned long xdnd_version = kMinXdndVersion;
424 XChangeProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("XdndAware"), 432 XChangeProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("XdndAware"),
425 XA_ATOM, 32, PropModeReplace, 433 XA_ATOM, 32, PropModeReplace,
426 reinterpret_cast<unsigned char*>(&xdnd_version), 1); 434 reinterpret_cast<unsigned char*>(&xdnd_version), 1);
427 } 435 }
428 436
429 DesktopDragDropClientAuraX11::~DesktopDragDropClientAuraX11() { 437 DesktopDragDropClientAuraX11::~DesktopDragDropClientAuraX11() {
430 g_live_client_map.Get().erase(xwindow_); 438 g_live_client_map.Get().erase(xwindow_);
439 // Make sure that all observers are unregistered from source and target
440 // windows. This may be necessary when the parent native widget gets destroyed
441 // while a drag operation is in progress.
442 NotifyDragLeave();
443 target_current_context_.reset();
sadrul 2014/03/26 18:01:07 You shouldn't need to do this. target_current_cont
varkha 2014/03/27 04:48:13 Done.
431 } 444 }
432 445
433 // static 446 // static
434 DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow( 447 DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow(
435 ::Window window) { 448 ::Window window) {
436 std::map< ::Window, DesktopDragDropClientAuraX11*>::const_iterator it = 449 std::map< ::Window, DesktopDragDropClientAuraX11*>::const_iterator it =
437 g_live_client_map.Get().find(window); 450 g_live_client_map.Get().find(window);
438 if (it == g_live_client_map.Get().end()) 451 if (it == g_live_client_map.Get().end())
439 return NULL; 452 return NULL;
440 return it->second; 453 return it->second;
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 687
675 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) { 688 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) {
676 gfx::Point screen_point(event->x_root, event->y_root); 689 gfx::Point screen_point(event->x_root, event->y_root);
677 690
678 if (source_state_ != SOURCE_STATE_OTHER) 691 if (source_state_ != SOURCE_STATE_OTHER)
679 return; 692 return;
680 693
681 // Find the current window the cursor is over. 694 // Find the current window the cursor is over.
682 ::Window mouse_window = None; 695 ::Window mouse_window = None;
683 ::Window dest_window = None; 696 ::Window dest_window = None;
684 FindWindowFor(screen_point, &mouse_window, &dest_window); 697 FindWindowFor(screen_point, &mouse_window, &dest_window,
698 atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_MENU"));
685 699
686 if (source_current_window_ != dest_window) { 700 if (source_current_window_ != dest_window) {
687 if (source_current_window_ != None) 701 if (source_current_window_ != None)
688 SendXdndLeave(source_current_window_); 702 SendXdndLeave(source_current_window_);
689 703
690 source_current_window_ = dest_window; 704 source_current_window_ = dest_window;
691 705
692 if (source_current_window_ != None) { 706 if (source_current_window_ != None) {
693 negotiated_operation_.erase(source_current_window_); 707 negotiated_operation_.erase(source_current_window_);
694 SendXdndEnter(source_current_window_); 708 SendXdndEnter(source_current_window_);
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 // GdkEvent about the failed drag. (And sending this message doesn't appear 1011 // GdkEvent about the failed drag. (And sending this message doesn't appear
998 // to go through normal xlib machinery, but instead passes through the low 1012 // to go through normal xlib machinery, but instead passes through the low
999 // level xProto (the x11 wire format) that I don't understand. 1013 // level xProto (the x11 wire format) that I don't understand.
1000 // 1014 //
1001 // I'm unsure if I have to jump through those hoops, or if XSendEvent is 1015 // I'm unsure if I have to jump through those hoops, or if XSendEvent is
1002 // sufficient. 1016 // sufficient.
1003 XSendEvent(xdisplay_, xid, False, 0, xev); 1017 XSendEvent(xdisplay_, xid, False, 0, xev);
1004 } 1018 }
1005 1019
1006 } // namespace views 1020 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698