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

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 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 static base::LazyInstance< 65 static base::LazyInstance<
65 std::map< ::Window, views::DesktopDragDropClientAuraX11*> >::Leaky 66 std::map< ::Window, views::DesktopDragDropClientAuraX11*> >::Leaky
66 g_live_client_map = LAZY_INSTANCE_INITIALIZER; 67 g_live_client_map = LAZY_INSTANCE_INITIALIZER;
67 68
68 // Helper class to FindWindowFor which looks for a drag target under the 69 // Helper class to FindWindowFor which looks for a drag target under the
69 // cursor. 70 // cursor.
70 class DragTargetWindowFinder : public ui::EnumerateWindowsDelegate { 71 class DragTargetWindowFinder : public ui::EnumerateWindowsDelegate {
71 public: 72 public:
72 DragTargetWindowFinder(XID ignored_icon_window, 73 DragTargetWindowFinder(XID ignored_icon_window,
74 Atom menu_type_atom,
73 gfx::Point screen_loc) 75 gfx::Point screen_loc)
74 : ignored_icon_window_(ignored_icon_window), 76 : ignored_icon_window_(ignored_icon_window),
75 output_window_(None), 77 output_window_(None),
78 menu_type_atom_(menu_type_atom),
76 screen_loc_(screen_loc) { 79 screen_loc_(screen_loc) {
77 ui::EnumerateTopLevelWindows(this); 80 ui::EnumerateTopLevelWindows(this);
78 } 81 }
79 82
80 virtual ~DragTargetWindowFinder() {} 83 virtual ~DragTargetWindowFinder() {}
81 84
82 XID window() const { return output_window_; } 85 XID window() const { return output_window_; }
83 86
84 protected: 87 protected:
85 virtual bool ShouldStopIterating(XID window) OVERRIDE { 88 virtual bool ShouldStopIterating(XID window) OVERRIDE {
86 if (window == ignored_icon_window_) 89 if (window == ignored_icon_window_)
87 return false; 90 return false;
88 91
89 if (!ui::IsWindowVisible(window)) 92 if (!ui::IsWindowVisible(window))
90 return false; 93 return false;
91 94
92 if (!ui::WindowContainsPoint(window, screen_loc_)) 95 if (!ui::WindowContainsPoint(window, screen_loc_))
93 return false; 96 return false;
94 97
95 if (ui::PropertyExists(window, "WM_STATE")) { 98 int value = 0;
99 if (ui::PropertyExists(window, "WM_STATE") ||
100 (ui::GetIntProperty(window, "_NET_WM_WINDOW_TYPE", &value) &&
101 static_cast<Atom>(value) == menu_type_atom_)) {
96 output_window_ = window; 102 output_window_ = window;
97 return true; 103 return true;
98 } 104 }
99 105
100 return false; 106 return false;
101 } 107 }
102 108
103 private: 109 private:
104 XID ignored_icon_window_; 110 XID ignored_icon_window_;
105 XID output_window_; 111 XID output_window_;
112 const Atom menu_type_atom_;
106 gfx::Point screen_loc_; 113 gfx::Point screen_loc_;
107 114
108 DISALLOW_COPY_AND_ASSIGN(DragTargetWindowFinder); 115 DISALLOW_COPY_AND_ASSIGN(DragTargetWindowFinder);
109 }; 116 };
110 117
111 // Returns the topmost X11 window at |screen_point| if it is advertising that 118 // Returns the topmost X11 window at |screen_point| if it is advertising that
112 // is supports the Xdnd protocol. Will return the window under the pointer as 119 // is supports the Xdnd protocol. Will return the window under the pointer as
113 // |mouse_window|. If there's a Xdnd aware window, it will be returned in 120 // |mouse_window|. If there's a Xdnd aware window, it will be returned in
114 // |dest_window|. 121 // |dest_window|.
115 void FindWindowFor(const gfx::Point& screen_point, 122 void FindWindowFor(const gfx::Point& screen_point,
116 ::Window* mouse_window, ::Window* dest_window) { 123 ::Window* mouse_window, ::Window* dest_window,
117 DragTargetWindowFinder finder(None, screen_point); 124 Atom menu_type_atom) {
125 DragTargetWindowFinder finder(None, menu_type_atom, screen_point);
118 *mouse_window = finder.window(); 126 *mouse_window = finder.window();
119 *dest_window = None; 127 *dest_window = None;
120 128
121 if (finder.window() == None) 129 if (finder.window() == None)
122 return; 130 return;
123 131
124 // Figure out which window we should test as XdndAware. If mouse_window has 132 // Figure out which window we should test as XdndAware. If mouse_window has
125 // XdndProxy, it will set that proxy on target, and if not, |target|'s 133 // XdndProxy, it will set that proxy on target, and if not, |target|'s
126 // original value will remain. 134 // original value will remain.
127 XID target = *mouse_window; 135 XID target = *mouse_window;
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 424
417 // Mark that we are aware of drag and drop concepts. 425 // Mark that we are aware of drag and drop concepts.
418 unsigned long xdnd_version = kMinXdndVersion; 426 unsigned long xdnd_version = kMinXdndVersion;
419 XChangeProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("XdndAware"), 427 XChangeProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("XdndAware"),
420 XA_ATOM, 32, PropModeReplace, 428 XA_ATOM, 32, PropModeReplace,
421 reinterpret_cast<unsigned char*>(&xdnd_version), 1); 429 reinterpret_cast<unsigned char*>(&xdnd_version), 1);
422 } 430 }
423 431
424 DesktopDragDropClientAuraX11::~DesktopDragDropClientAuraX11() { 432 DesktopDragDropClientAuraX11::~DesktopDragDropClientAuraX11() {
425 g_live_client_map.Get().erase(xwindow_); 433 g_live_client_map.Get().erase(xwindow_);
434 // Make sure that all observers are unregistered from source and target
435 // windows. This may be necessary when the parent native widget gets destroyed
436 // while a drag operation is in progress.
437 NotifyDragLeave();
438 target_current_context_.reset();
426 } 439 }
427 440
428 // static 441 // static
429 DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow( 442 DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow(
430 ::Window window) { 443 ::Window window) {
431 std::map< ::Window, DesktopDragDropClientAuraX11*>::const_iterator it = 444 std::map< ::Window, DesktopDragDropClientAuraX11*>::const_iterator it =
432 g_live_client_map.Get().find(window); 445 g_live_client_map.Get().find(window);
433 if (it == g_live_client_map.Get().end()) 446 if (it == g_live_client_map.Get().end())
434 return NULL; 447 return NULL;
435 return it->second; 448 return it->second;
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 DCHECK_EQ(target_window_, window); 673 DCHECK_EQ(target_window_, window);
661 target_window_ = NULL; 674 target_window_ = NULL;
662 } 675 }
663 676
664 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) { 677 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) {
665 gfx::Point screen_point(event->x_root, event->y_root); 678 gfx::Point screen_point(event->x_root, event->y_root);
666 679
667 // Find the current window the cursor is over. 680 // Find the current window the cursor is over.
668 ::Window mouse_window = None; 681 ::Window mouse_window = None;
669 ::Window dest_window = None; 682 ::Window dest_window = None;
670 FindWindowFor(screen_point, &mouse_window, &dest_window); 683 FindWindowFor(screen_point, &mouse_window, &dest_window,
684 atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_MENU"));
671 685
672 if (source_current_window_ != dest_window) { 686 if (source_current_window_ != dest_window) {
673 if (source_current_window_ != None) 687 if (source_current_window_ != None)
674 SendXdndLeave(source_current_window_); 688 SendXdndLeave(source_current_window_);
675 689
676 source_current_window_ = dest_window; 690 source_current_window_ = dest_window;
677 691
678 if (source_current_window_ != None) { 692 if (source_current_window_ != None) {
679 negotiated_operation_.erase(source_current_window_); 693 negotiated_operation_.erase(source_current_window_);
680 SendXdndEnter(source_current_window_); 694 SendXdndEnter(source_current_window_);
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 // GdkEvent about the failed drag. (And sending this message doesn't appear 974 // GdkEvent about the failed drag. (And sending this message doesn't appear
961 // to go through normal xlib machinery, but instead passes through the low 975 // to go through normal xlib machinery, but instead passes through the low
962 // level xProto (the x11 wire format) that I don't understand. 976 // level xProto (the x11 wire format) that I don't understand.
963 // 977 //
964 // I'm unsure if I have to jump through those hoops, or if XSendEvent is 978 // I'm unsure if I have to jump through those hoops, or if XSendEvent is
965 // sufficient. 979 // sufficient.
966 XSendEvent(xdisplay_, xid, False, 0, xev); 980 XSendEvent(xdisplay_, xid, False, 0, xev);
967 } 981 }
968 982
969 } // namespace views 983 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698